Re: onsuccess callback in race condition?

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.

Hope that helps and thanks for reviewing the spec!

/ Jonas

Received on Thursday, 15 July 2010 17:51:08 UTC