David Bruant bruant.d at
Tue Nov 13 06:21:13 PST 2012

Le 09/11/2012 17:33, Mark S. Miller a écrit :
> Hi David, thanks for your thoughtful post. I've always used the 
> two-arg form of .then[1], but your post makes a strong case for more 
> often using separate one-arg .then and .fail calls. I say only "more 
> often" because the two arg form can easily make distinctions that the 
> one-arg forms cannot
>     var p2 = Q(p1).then(val => { throw foo(val); },
> reason => { return bar(reason); });
> is different than either of the one-arg chainings. It'll be 
> interesting to look over old code and see how often this difference 
> matters. My guess is it usually doesn't, in which case your style 
> should dominate.
Interesting example. Let's compare it with:

     var p2 = p1.then(val => { throw foo(val); })
                        .fail(reason => { return bar(reason); });

With this given order, the .fail catches the error in the .then callback.
There is an information loss in the fact that in the fail callback, it 
may not be clear whether the error came from p1 or the .then callback. 
In my experience, it was never a worthwhile distinction (I just cared 
about "an error happened somewhere"), so I guess the 80% case is covered.

In case it really matters, the value thrown in the .then could be made 
distinguishable from expected thrown errors of p1 so that the callback 
can compare and choose a different behavior for each case.
Also, it's still possible to hook the .fail to p1 directly if necessary.

I feel the one-arg version works fine. As you pointed out, there is a 
minor information loss, but it's not that hard to work around in the 
cases where it matters (I've seen you seem to agree, but I felt it was 
important to do the analysis of the differences in both cases).

> [1] In my code and in my Q specs 
> <> and 
> implementations 
> <>, 
> I have been using "when" rather than "then". Because these are 
> otherwise compatible AFAICT with A+, for the sake of consensus I'm 
> willing to change this to "then" everywhere. But before I do, I'd like 
> to make one last plea for "when" and see how this community responds.
> The word "when" is clearly temporal, and suggests postponing something 
> until some enabling condition. This seems perfect. The word "then" in 
> programming is most closely associated with the concept of an "if then 
> else", even though curly bracket languages never spell out the "then". 
> When I look at your .then/.fail examples, the first thought that 
> always pops into my head is "Shouldn't the opposite of .then be .else 
> ?" Of course .fail is appropriate and .else is not. But isn't .then 
> inappropriate for the same reason?
I have to admit that I haven't paid close attention. For me, .then felt 
relevant as a form of punctuation like semi-colons for the synchronous 


     // akin to
     var p2 = doThis(p);
     var p3 = doThat(p2);

JavaScript is a bit special with semicolon, but in some other major 
languages, a semi-colon is a language construct to separate 2 steps in 
an algorithm and mean "do this then that".
I used .then because of my experience with Q, but if "when" is more 
accurate, I'll be fine with when.

> On Fri, Nov 9, 2012 at 4:33 AM, David Bruant <bruant.d at 
> <mailto:bruant.d at>> wrote:
>     [...]
>     ## Q.all
>     My favorite feature is the Q.all function. Q.all accepts an array
>     of promises and returns a promise which will be fulfilled when all
>     promises are. The resolution values are the different promises
>     resolution values:
>         var someData1P = query(q1);
>         var someData2P = query(q2);
>         var someData3P = fetch(url); // HTTP GET returning a promise
>         Q.all([someData1P, someData2P, someData3P])
>             .then(function(someData1, someData2, someData3){
>                 // do something when all data are back
>             })
>     I used this extensively and it's been extremely helpful.
>     Personally, to synchronize different async operations, I've never
>     read code more elegant than what Q.all offers. I'm interested in
>     hearing what other's experience is on that point.
>     Arguably, Q.all could take several arguments instead of accepting
>     only an array (that's one thing I'd change). Maybe there is a good
>     reason to enforce an array, but I don't know it.
> I originally speced it to take varargs, but I was thinking in ES6 
> terms where "..." is already supported. Kris Kowal points out that 
> most usage of Q today, for obvious reasons, is pre-ES6. The var-args 
> form means that a Q.all on a computed list would require usage of 
> .apply, which is much uglier than the extra square brackets for the 
> non-computed case.
That makes a lot of sense.
Assuming arrays and promises are unambiguously distinguishable, the 
Q.all feature could be polymorphic and take either one array as argument 
or a bunch or promises and have the expected behavior in each case.

>     # Promises and progress
>     Since I started talking about promises, I've had discussions with
>     people and one thing that came about a couple of times was the
>     idea of "progress" or how promises relate to streams.
>     The way I see promises, they have 3 states:
>     unfulfilled/resolved/broken.
> Sigh. The fact that even you get confused on the terminology makes me 
> think that no state should ever be named "un" anything. Let's stick 
> with the A+ terminology: pending/fulfilled/rejected.
Sounds good to me. I'll pull my "non-native English speaker" card here, 
because I don't understand the difference between your terminology and 
the one I chose.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list