W3C home > Mailing lists > Public > public-webapps@w3.org > July to September 2010

Re: onsuccess callback in race condition?

From: Jonas Sicking <jonas@sicking.cc>
Date: Thu, 15 Jul 2010 13:52:54 -0700
Message-ID: <AANLkTikFi8QGYFJznXvU7au4WhCuMbwIJJ52nYEBhlra@mail.gmail.com>
To: "victor.hong@nokia.com" <victor.hong@nokia.com>
Cc: "public-webapps@w3.org" <public-webapps@w3.org>
On Thursday, July 15, 2010,  <victor.hong@nokia.com> wrote:
>
>
>
> On 7/15/10 1:50 PM, "ext Jonas Sicking" <jonas@sicking.cc> wrote:
>
>> On Thu, Jul 15, 2010 at 8:13 AM,  <victor.hong@nokia.com> wrote:
>>> Hi,
>>>
>>> I would like to get some clarification on async implementation of the
>>> indexedDB API.
>>>
>>> Example 1:
>>> Below is a sample code from the following blog article.
>>> http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/
>>>
>>> var request = window.indexedDB.open("CandyDB",
>>>                                    "My candy store database");
>>> request.onsuccess = function(event) {
>>>  var db = event.result;
>>>  if (db.version != "1") {
>>>    // User's first visit, initialize database.
>>>    var createdObjectStoreCount = 0;
>>>    var objectStores = [
>>>      { name: "kids", keyPath: "id", autoIncrement: true },
>>>      { name: "candy", keyPath: "id", autoIncrement: true },
>>>      { name: "candySales", keyPath: "", autoIncrement: true }
>>>    ];
>>>
>>>    function objectStoreCreated(event) {
>>>      if (++createdObjectStoreCount == objectStores.length) {
>>>        db.setVersion("1").onsuccess = function(event) {
>>>          loadData(db);
>>>        };
>>>      }
>>>    }
>>>
>>>    for (var index = 0; index < objectStores.length; index++) {
>>>      var params = objectStores[index];
>>>      request = db.createObjectStore(params.name, params.keyPath,
>>>                                     params.autoIncrement);
>>>      request.onsuccess = objectStoreCreated;
>>>    }
>>>  }
>>>  else {
>>>    // User has been here before, no initialization required.
>>>    loadData(db);
>>>  }
>>> };
>>>
>>> In this code, request is returned from request = window.indexedDB.open()
>>> call, then request.onsuccess = function() {...} is assigned.
>>>
>>> Maybe I don't fully understand how this IndexedDB works,
>>> it seems that there could be a race condition between the open() operation
>>> and request.onsuccess assignment. The open() operation could be completed
>>> before request.onsuccess got assigned to a callback function. Does this mean
>>> that the request.onsuccess callback function will not be called?
>>
>> No.
>>
>> Since the 'success' event fires asynchronously, it will never fire
>> until you've returned to the main event loop. In other words, while we
>> might actually finish the request before .onsuccess gets called, all
>> that is done when the request is finished is to post an "task" to the
>> main event loop. Only once this "task" runs, the 'success' event is
>> fired. Thus you have lots of time to set the .onsuccess property
>> before the event could possibly fire. This is not specific to
>> IndexedDB, there are lots of specifications that work this way.
>> Consider the following similar code:
>>
>> xhr = new XMLHttpRequest();
>> xhr.open(...);
>> xhr.send(...);
>> xhr.onload = myHandler;
>>
>> This is completely safe. While we might finish loading the resource
>> before .onload is set (for example if we're loading from cache), the
>> 'load' event can only be fired after we've returned to the main event
>> loop.
>
>
>  So you mean by the time control return to the main event loop of the
>  browser, request.onsuccess= mycallback would have been executed, even
> though
>  the request has been finished but it only post a "task" to the main event
> loop
>  waiting to be fired.

Yes.

/ Jonas
Received on Thursday, 15 July 2010 20:53:27 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:39 GMT