- From: Jeremy Orlow <jorlow@chromium.org>
- Date: Tue, 2 Mar 2010 14:22:54 +0000
- To: Kris Zyp <kris@sitepen.com>, Joseph Pecoraro <joepeck02@gmail.com>
- Cc: public-webapps <public-webapps@w3.org>
- Message-ID: <5dd9e5c51003020622w6551eeb7rff6ad26d2158149f@mail.gmail.com>
On Mon, Mar 1, 2010 at 9:52 PM, Jeremy Orlow <jorlow@chromium.org> wrote: > Thanks for the pointers. I'm actually pretty sold on the general idea of > promises, and my intuition is that there won't be a very big resource > penalty for using an API like this rather than callbacks or what's currently > specced. At the same time, it seems as though there isn't much of a > standard in terms of the precise semantics and some of the techniques (such > as optionally taking callbacks and not returning a promise if they are > supplied) seems like a decent answer for pure javascript APIs, but maybe not > as good for IDL and a standard like this. > > Do you guys have any recommendations for the precise semantics we'd use, if > we used promises in IndexedDB? To get started, let me list what I'd propose > and maybe you can offer counter proposals or feedback on what would or > wouldn't work? > > > Each method on a ____Request interface (the async ones in the spec) whose > counterpart returns something other than void would instead return a > Promise. > > The promises would only have a "then" method which would take in an > onsuccess and onerror callback. Both are optional. The onsuccess function > should take in a single parameter which matches the return value of the > synchronous counterpart. The onerror function should take in an > IDBDatabaseError. If the callbacks are null, undefined, or omitted, they're > ignored. If they're anything else, we should probably either raise an > exception immediately or ignore them. > > If there's an error, all onerror callbacks would be called with the > IDBDatabaseError. > > Exceptions within callbacks would be ignored. > Oh. And the callbacks should probably be enqueued in the main event loop when the result/error is ready. This way, even if the result is already available when .then() is called, an implementation won't simply call the callback immediately (in a nested fashion). This will ensure consistent behavior despite implementational differences and races. > In terms of speccing, I'm not sure if we can get away with speccing one > promise interface or whether we'd need to create one for each type of > promise. > > > On Thu, Feb 18, 2010 at 4:20 PM, Kris Zyp <kris@sitepen.com> wrote: > >> -----BEGIN PGP SIGNED MESSAGE----- >> Hash: SHA1 >> >> >> >> On 2/18/2010 5:31 AM, Jeremy Orlow wrote: >> > On Wed, Jan 27, 2010 at 9:46 PM, Kris Zyp <kris@sitepen.com >> > <mailto:kris@sitepen.com> <kris@sitepen.com>> wrote: >> > >> > * Use promises for async interfaces - In server side JavaScript, >> > most >> > projects are moving towards using promises for asynchronous >> > interfaces >> > instead of trying to define the specific callback parameters for >> > each >> > interface. I believe the advantages of using promises over callbacks >> > are pretty well understood in terms of decoupling async >> > semantics from >> > interface definitions, and improving encapsulation of concerns. For >> > the indexed database API this would mean that sync and async >> > interfaces could essentially look the same except sync would return >> > completed values and async would return promises. I realize that >> > defining a promise interface would have implications beyond the >> > indexed database API, as the goal of promises is to provide a >> > consistent interface for asynchronous interaction across components, >> > but perhaps this would be a good time for the W3C to define such an >> > API. It seems like the indexed database API would be a perfect >> > interface to leverage promises. If you are interested in proposal, >> > there is one from CommonJS here [1] (the get() and call() wouldn't >> > apply here). With this interface, a promise.then(callback, >> > errorHandler) function is the only function a promise would need to >> > provide. >> > >> > >> > [1] http://wiki.commonjs.org/wiki/Promises >> > >> > >> > Very interesting. The general concept seems promising and fairly >> > flexible. You can easily code in a similar style to normal >> > async/callback semantics, but it seems like you have a lot more >> > flexibility. I do have a few questions though. >> > >> > Are there any good examples of these used in the wild that you can >> > point me towards? I used my imagination for prototyping up some >> > examples, but it'd be great to see some real examples + be able to >> > see the exact semantics used in those implementations. >> >> >> Promises are heavily used in the E programming language, the Twisted >> project (python). In JavaScript land, Dojo's Deferred's are an example >> of a form of promises and a number of SSJS projects including Node and >> Narwhal. To see some examples, you can look at the Dojo's docs [1] >> (note that Dojo's spells it "addCallback" and "addErrback" instead of >> "then", however we are looking to possibly move to the CommonJS >> promise for Dojo 2.0). Here is somewhat random example of module that >> uses Deferred's [2] >> [1] http://api.dojotoolkit.org/jsdoc/1.3/dojo.Deferred >> [2] >> >> http://download.dojotoolkit.org/release-1.4.1/dojo-release-1.4.1/dojox/rpc/JsonRest.js >> >> >> >> > >> > I see that you can supply an error handling callback to .then(), but >> > does that only apply to the one operation? I could easily imagine >> > emulating try/catch type semantics and have errors continue down the >> > line of .then's until someone handles it. It might even make sense >> > to allow the error handlers to re-raise (i.e. allow to >> > bubble) errors so that later routines would get them as well. >> Yes, that's exactly right, errors can be raised/thrown and propagate >> (when an error handling callback is not provided) to the next promise, >> and be caught (with an error handler) just as you have expected from >> the analogous propagation of errors across stack frames in JS. >> >> >> > Maybe you'd even want it to bubble by default? What have other >> > implementations done with this stuff? What is the most robust and >> > least cumbersome for typical applications? (And, in te complete >> > absence of real experience, are there any expert opinions on what >> > might work?) >> > >> I think it is pretty clear you want propagation, just like with normal >> sync errors, it is very handy to have a catch/error handler low down >> in the stack to generically handle various errors. >> >> > Overall this seems fairly promising and not that hard to implement. >> > Do others see pitfalls that I'm missing? >> >> There are certainly numerous design decisions that can be made with >> promises. >> * If an error occurs and an error handler is not provided in the >> current event turn (note that an event handler can be provided at any >> point in the future), should the error be logged somewhere? >> * If an callback handler is added to an already fulfilled promise, >> should the callback be executed immediately or in the next event turn? >> Most JS impls execute immediately, but E suggests otherwise. >> * One pitfall that a number of prior implementations have made is in >> having callback's return value mutate the current promise instead of >> returning the new one, the CommonJS spec makes it clear that then() >> should return a new promise that receives the return values from the >> callback. >> >> - -- >> Kris Zyp >> SitePen >> (503) 806-1841 >> http://sitepen.com >> -----BEGIN PGP SIGNATURE----- >> Version: GnuPG v1.4.9 (MingW32) >> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ >> >> iEYEARECAAYFAkt9aNIACgkQ9VpNnHc4zAxMBgCfUG0/CVTgV15MBe8uQRDc6RPW >> CwkAnjRiwt75g6yUpZ2dnnY5gv0LYpmh >> =R2Qj >> -----END PGP SIGNATURE----- >> >> >
Received on Tuesday, 2 March 2010 14:23:46 UTC