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
<http://wiki.ecmascript.org/doku.php?id=strawman:concurrency> and
implementations
<http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/makeQ.js>,
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
style:
p.then(doThis)
.then(doThat)
.then(...)
// 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 <[email protected]
<mailto:[email protected]>> 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.
David
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss