W3C home > Mailing lists > Public > public-webapps@w3.org > January to March 2010

Re: [IndexedDB] Promises (WAS: Seeking pre-LCWD comments for Indexed Database API; deadline February 2)

From: Jeremy Orlow <jorlow@chromium.org>
Date: Tue, 2 Mar 2010 14:22:54 +0000
Message-ID: <5dd9e5c51003020622w6551eeb7rff6ad26d2158149f@mail.gmail.com>
To: Kris Zyp <kris@sitepen.com>, Joseph Pecoraro <joepeck02@gmail.com>
Cc: public-webapps <public-webapps@w3.org>
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 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:37 GMT