NOTE: I'm not proposing we do any major modifications like switching from an event based system (aka callbacks) to using promises.
All I'm suggesting we do is adopt the proposal I made in the initial email in this thread. However I am saying that one of the reasons for adopting that proposal is that it allows *libraries* to more easily build a promise system on top of our API. Or integrate indexedDB in their already-existing promises implementation. / Jonas On Mon, Jan 10, 2011 at 2:00 PM, Keean Schupke <ke...@fry-it.com> wrote: > Whats wrong with callbacks? To me this seems an unnecessary complication. > Presumably you would do: > var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > var result = promise.get(); > if (!result) { > promise.onsuccess(function(res) {...X...}); > } else { > ...Y... > } > > So you end up having to duplicate code at X and Y to do the same thing > directly or in the context of a callback. Or you define a function to > process the result: > var f = function(res) {...X...}; > var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > var result = promise.get(); > if (!result) { > promise.onsuccess(f); > } else { > f(result) > }; > But in which case what advantage does all this extra clutter offer over: > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess(function(res) > {...X...}); > > I am just wondering whether the change is worth the added complexity? > > Cheers, > Keean. > > On 10 January 2011 21:31, Jonas Sicking <jo...@sicking.cc> wrote: >> >> I did some outreach to developers and while I didn't get a lot of >> feedback, what I got was positive to this change. >> >> The basic use-case that was brought up was implementing a promises >> which, as I understand it, works similar to the request model I'm >> proposing. I.e. you build up these "promise" objects which represent a >> result which may or may not have arrived yet. At some point you can >> either read the value out, or if it hasn't arrived yet, register a >> callback for when the value arrives. >> >> It was pointed out that this is still possible with how the spec is >> now, but it will probably result in that developers will come up with >> conventions to set the result on the request themselves. This wouldn't >> be terribly bad, but also seems nice if we can help them. >> >> / Jonas >> >> On Mon, Jan 10, 2011 at 8:13 AM, ben turner <bent.mozi...@gmail.com> >> wrote: >> > FWIW Jonas' proposed changes have been implemented and will be >> > included in Firefox 4 Beta 9, due out in a few days. >> > >> > -Ben >> > >> > On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking <jo...@sicking.cc> >> > wrote: >> >> I've been reaching out to get feedback, but no success yet. Will >> >> re-poke. >> >> >> >> / Jonas >> >> >> >> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow <jor...@chromium.org> >> >> wrote: >> >>> Any additional thoughts on this? If no one else cares, then we can go >> >>> with >> >>> Jonas' proposal (and we should file a bug). >> >>> J >> >>> >> >>> On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow <jor...@chromium.org> >> >>> wrote: >> >>>> >> >>>> On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking <jo...@sicking.cc> >> >>>> wrote: >> >>>>> >> >>>>> Hi All, >> >>>>> >> >>>>> One of the things we briefly discussed at the summit was that we >> >>>>> should make IDBErrorEvents have a .transaction. This since we are >> >>>>> allowing you to place new requests from within error handlers, but >> >>>>> we >> >>>>> currently provide no way to get from an error handler to any useful >> >>>>> objects. Instead developers will have to use closures to get to the >> >>>>> transaction or other object stores. >> >>>>> >> >>>>> Another thing that is somewhat strange is that we only make the >> >>>>> result >> >>>>> available through the success event. There is no way after that to >> >>>>> get >> >>>>> it from the request. So instead we use special event interfaces with >> >>>>> supply access to source, transaction and result. >> >>>>> >> >>>>> Compare this to how XMLHttpRequests work. Here the result and error >> >>>>> code is available on the request object itself. The 'load' event, >> >>>>> which is equivalent to our 'success' event didn't supply any >> >>>>> information until we recently added progress event support. But >> >>>>> still >> >>>>> it only supplies information about the progress, not the actual >> >>>>> value >> >>>>> itself. >> >>>>> >> >>>>> One thing we could do is to move >> >>>>> >> >>>>> .source >> >>>>> .transaction >> >>>>> .result >> >>>>> .error >> >>>>> >> >>>>> to IDBRequest. Then make "success" and "error" events be simple >> >>>>> events >> >>>>> which only implement the Event interface. I.e. we could get rid of >> >>>>> the >> >>>>> IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent >> >>>>> interfaces. >> >>>>> >> >>>>> We'd still have to keep IDBVersionChangeEvent, but it can inherit >> >>>>> Event directly. >> >>>>> >> >>>>> The request created from IDBFactory.open would return a IDBRequest >> >>>>> where .transaction and .source is null. We already fire a IDBEvent >> >>>>> where .source is null (actually, the spec currently doesn't define >> >>>>> what the source should be I see now). >> >>>>> >> >>>>> >> >>>>> The only major downside with this setup that I can see is that the >> >>>>> current syntax: >> >>>>> >> >>>>> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> >>>>> function(e) { >> >>>>> alert(e.result); >> >>>>> } >> >>>>> >> >>>>> would turn into the slightly more verbose >> >>>>> >> >>>>> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> >>>>> function(e) { >> >>>>> alert(e.target.result); >> >>>>> } >> >>>>> >> >>>>> (And note that with the error handling that we have discussed, the >> >>>>> above code snippets are actually plausible (apart from the alert() >> >>>>> of >> >>>>> course)). >> >>>>> >> >>>>> The upside that I can see is that we behave more like >> >>>>> XMLHttpRequest. >> >>>>> It seems that people currently follow a coding pattern where they >> >>>>> place a request and at some later point hand the request to another >> >>>>> piece of code. At that point the code can either get the result from >> >>>>> the .result property, or install a onload handler and wait for the >> >>>>> result if it isn't yet available. >> >>>>> >> >>>>> However I only have anecdotal evidence that this is a common coding >> >>>>> pattern, so not much to go on. >> >>>> >> >>>> Here's a counter proposal: Let's add .transaction, .source, and >> >>>> .result >> >>>> to IDBEvent and just specify them to be null when there is no >> >>>> transaction, >> >>>> source, and/or result. We then remove readyState from IDBResult as >> >>>> it >> >>>> serves no purpose. >> >>>> What I'm proposing would result in an API that's much more similar to >> >>>> what >> >>>> we have at the moment, but would be a bit different than XHR. It is >> >>>> definitely good to have similar patterns for developers to follow, >> >>>> but I >> >>>> feel as thought the model of IndexedDB is already pretty different >> >>>> from XHR. >> >>>> For example, method calls are supplied parameters and return an >> >>>> IDBRequest >> >>>> object vs you using new to create the XHR object and then making >> >>>> method >> >>>> calls to set it up and then making a method call to start it. In >> >>>> fact, if >> >>>> you think about it, there's really not that much XHR and IndexedDB >> >>>> have in >> >>>> common except that they use event handlers. >> >>>> As for your proposal, let me think about it for a bit and forward it >> >>>> on to >> >>>> some people I know who are playing with IndexedDB already. >> >>>> J >> >>> >> >> >> >> >> > >> > >