Re: [IndexedDB] onsuccess callback in race condition?

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.

Thanks for responding

> 
> Hope that helps and thanks for reviewing the spec!
> 
> / Jonas
> 

Received on Thursday, 15 July 2010 19:32:06 UTC