[dojo-contributors] Promises

Bill Keese bill at dojotoolkit.org
Thu Mar 4 04:44:10 EST 2010

Thanks for working on this 
(http://bugs.dojotoolkit.org/attachment/ticket/10814/Deferred.js).    I 
tested it out and it seems to be working, not sure if you have a test 
file but I wrote a bunch of tests and uploaded them to 
http://bugs.dojotoolkit.org/attachment/ticket/10814/Deferred.2.js.   No 
tests about progress or the canceller, you should add some tests for that.

A few minor things:
    - What's the relation between Promise and Deferred in your code (why 
are there two classes)?   I thought there would be a dojo.Promise class 
but there isn't, just a local variable called Promise.
    - the code sort-of violates our consensus to move away from private 
functions in closures (ex: an app can't modify Deferred.complete() 
without changing the whole Deferred function)

We talked about performance in the meeting and Eugene/my worries from 
http://thread.gmane.org/gmane.comp.web.dojo.devel/12358/focus=12377.  I 
thought about it some more and I'm not too worried,  although there will 
be many more Deferred's in dojo 2.0 than in dojo 1.x.

One common case where then() will be called thousands of times is with 
the dojo.data (at least for a server based store).  I'm assuming that 
although a store will internally fetch batches of rows from the server, 
the store API will be to get one row at a time, and that iterator 
function will return a Deferred.

There will also probably be some cases where then() is called many times 
on the same Deferred, but hopefully not enough to be an issue.   For 
example a FilteringSelect might return a Deferred from attr("value") 
because it's value is not always immediately available (it requires a 
lookup in the data store mapping what the user typed, like "california", 
into a value like "CA".  And FilteringSelect.attr("value") could be 
called many times by (for example) form level code that keeps querying 
the value of all the form widgets.  Same thing for widget error state 
(myFormWidget.attr("state")), error state might not be immediately 
available so that attr("state") would return as a boolean Deferred.

Kris Zyp wrote:
> On 3/3/2010 3:47 PM, James Burke wrote:
>> On Wed, Mar 3, 2010 at 2:10 PM, Kris Zyp <kzyp at dojotoolkit.org> wrote:
>>> I put together a backwards compatible variant of this implementation.
>> This sounds promising. Ha, see what I did there? OK, that already
>> sounds lame to me after just saying it.
>> Anyway, I am keen to see this in a 1.5, even better if it meshes with
>> the CommonJS Promises. However it seemed like the CommonJS version was
>> still in flux? Kris, how do view the state of the process/progress
>> over in CommonJS-land?
> As far as possible CommonJS objectors go, I know that Ryan Dahl wanted
> to use his own API, but subsequently has completely removed promises
> from Node, so I don't think he/they are proposing any alternatives (and
> I wrote a node-promise module for Node to provide promises for those
> that still want them in Node, which is based on the CommonJS proposal,
> and I think that is the main promise option for Node users now).
> The only real alternative that has been discussed is Tyler Close's
> ref_send based promises. Promises with his library are functions that
> take several unintuitive arguments, and are intentionally designed to be
> awkward to use directly so that people will use the static functions to
> enforce more invariants. Of course we can still provide such
> invariant-enforcing functions, and the primary one, when() is included
> in my dojo.Deferred module. I don't think we need to make
> promises/deferreds hard to use directly in the process though, and I
> don't think are users would be very happy if we made promises are harder
> to use. So I don't think this is a realistic alternative even if it does
> show up as a CommonJS proposal someday (note that CommonJS just consists
> of proposals and information on implementations, there is no real
> "blessed" specs in CommonJS), and I doubt it would ever see significant
> implementation breadth.
>>  Any possible implementation divergence between
>> our code and theirs?
>> I am also not so keen on a setTimeout for the error case. It means we
>> need a setTimeout implementation for whatever environment runs the
>> code, and for debugging, it loses the stack trace.
>> I appreciate that it is a hard thing to sort out. Some
>> Deferred/Promise use expect errors to just be eaten but other uses
>> what to know about errors. The basic problem seems to be not knowing
>> the error intention at the point of calling the reject/errback.
>> With traditional Dojo use of Deferreds, it seemed almost reasonable to
>> say if there was no errback listeners when the error is thrown we can
>> just throw in that case.
> The real problem is that it is actually very common for a deferred to be
> rejected (go into error state) *before* callbacks can ever be added. For
> example:
> dojo.xhrGet({ sync:true, ...}).addErrback(function(){ ... handle the
> error...});
> If there is an error in the XHR request, the deferred/promise object
> will go into an error state prior to the error handler being added, but
> clearly in this example the user is explicitly providing a handler for
> errors. By waiting for the next event turn (doing a setTimeout), we
> allow the entire call stack to be executed (and allowing any point in
> the call stack to add an error handler) before determining if an error
> is going to be caught or uncaught (and if uncaught, logged to the
> console, per Eugene's suggestion).
>> However, with a dojo.when(something, callback, errback) sort of
>> approach, the errback listener is likely not be be bound until after
>> the something's Deferred may have erred out? I'm thinking out loud a
>> bit here, maybe Kris or Eugene have other suggestions on how to look
>> at the problem.
>> Making sure these things are easy to debug is a pretty big deal. After
>> spending some time in Twisted land, and dealing with the current state
>> of dojo.Deferred error debugging, tracking down errors effectively
>> would make this sort of deferred/async logic a lot easier to get into.
> Yes, I definitely agree, and the details of error handling and trying to
> detect uncaught errors is probably one of the trickiest parts of promises.
> Kris
> _______________________________________________
> dojo-contributors mailing list
> dojo-contributors at mail.dojotoolkit.org
> http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors

More information about the dojo-contributors mailing list