- From: ben turner <bent.mozilla@gmail.com>
- Date: Thu, 6 May 2010 13:23:00 -0700
- To: public-webapps WG <public-webapps@w3.org>
Hi folks, We've been playing around with the async API and have made some changes to the IDBRequest interface that we'd like feedback on and hopefully inclusion in the spec. Here's what we have now: interface IDBRequest : EventTarget { void abort(); const unsigned short INITIAL = 0; const unsigned short LOADING = 1; const unsigned short DONE = 2; readonly attribute unsigned short readyState; attribute Function onsuccess; attribute Function onerror; }; interface IDBEvent : Event { readonly attribute Any source; }; interface IDBSuccessEvent : IDBEvent { readonly attribute Any result; }; interface IDBErrorEvent : IDBEvent { readonly attribute unsigned short code; readonly attribute DOMString message; }; First, the obvious stuff. We've moved the error and result property from the request to their respective events. Having everything on the event makes it much easier to write callback functions, in my opinion. Example in a sec. We've also made the success and error event keep a source property that can be used to get back to the object that generated the request. This may be a bit confusing but the example will help. Here we go: The following code uses the old API to put two values into an object store and then alert the two keys that were created. We're assuming that the object store "Data" exists and is an autoIncrementing store. var request = indexedDB.open("MyDB", "My Cool Database"); request.onsuccess = function(event) { // request.result is an IDBDatabaseRequest var request2 = request.result.openObjectStore("Data"); request2.onsuccess = function(event) { // request2.result is an IDBObjectStoreRequest var objectStore = request2.result; var request3 = objectStore.put("foo"); request3.onsuccess = function(event) { // request3.result is a key value var key1 = request3.result; var request4 = objectStore.put("bar"); request4.onsuccess = function(event) { // request4.result is a key value var key2 = request4.result; alert("All done, keys are " + key1 + " and " + key2); }; request4.onerror = function(event) { alert(request4.error.message); }; }; request3.onerror = function(event) { alert(request3.error.message); }; }; request2.onerror = function(event) { alert(request2.error.message); }; }; request.onerror = function(event) { alert(request.error.message); }; >From that sample you can see that the error functions are almost identical but they have to keep track of the proper request that created them in order to get the right error message. The success functions also have to keep track of the request that created them to know what the result property contains. Note also that we have to save objectStore in request2.onsuccess in order to do an additional put into the object store in request3.onsuccess. Keeping track of all of this is really tedious and error prone. With the changes outlined above, this code can be condensed to the following: function errorHandler(event) { // event.source is different each time here but can be used to figure out which operation failed // event.code holds the error code alert(event.message); } var request = indexedDB.open("MyDB", "My Cool Database"); request.onerror = errorHandler; request.onsuccess = function(event) { // event.source is an IndexedDatabaseRequest // event.result is an IDBDatabaseRequest request = event.result.openObjectStore("Data"); request.onerror = errorHandler; request.onsuccess = function(event) { // event.source is an IDBDatabaseRequest // event.result is an IDBObjectStoreRequest request = event.result.put("foo"); request.onerror = errorHandler; request.onsuccess = function(event) { // event.source is an IDBObjectStoreRequest // event.result is a key value var key1 = event.result; request = event.source.put("bar"); request.onerror = errorHandler; request.onsuccess = function(event) { // event.source is an IDBObjectStoreRequest // event.result is a key value var key2 = event.result; alert("All done, keys are " + key1 + " and " + key2); }; }; }; }; We haven't done much to compress the length of the script here, but you'll notice that each success handler is relatively self contained and doesn't really need to use closures to perform further operations. There's also no need to remember keep track of whether or not you want request3 or request2 or request5000. The error handler is much easier to reuse as well. So, what do you guys think? -Ben
Received on Thursday, 6 May 2010 20:40:19 UTC