New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi-yield for Q.async? #440
Comments
I am sympathetic to how nice this is, but am not a big fan of overloaded behavior in general. Converting whatever is One thing that seems apparent from how much people want this feature is that it would be worthwhile doing in ES7-timeframe await all [asyncOp1(), asyncOp2(), asyncOp3()]; /cc @erights @lukehoban |
I share your concerns about overloading; we don't want it to turn into the JavaScript In this case, I can't think of a practical use for Having a separate keyword would be better, but since ES7 is quite a long way off, we have to thread any functionality we want through the |
@domenic Why would you convert everything to promise? I am pretty sure you can't |
It's possible you have some value and you neither know nor care whether it's a promise or an actual value. Then |
In such cases you can explicitly just
|
Agree that requiring an explicit |
This seems pretty reasonable to me, especially given that in Q yield Q(maybePromise); It's still weird IMO to have that much magic packed into the type of the argument. I.e., you can yield two things, promises and arrays, and if it's arrays, we do this parallel thing... |
It's interesting that yield Q.all([promiseA, promiseB, promiseC]); is equivalent to [yield promiseA, yield promiseB, yield promiseC]; but unfortunately yield Q.all([asyncOp1(), asyncOp2(), asyncOp3()]); is not equivalent to [yield asyncOp1(), yield asyncOp2(), yield asyncOp3()]; |
Yes, that's a good way of putting it, and I think explains why |
If you prefer, you can think of Anyway, I think I've said all there is to be said on the topic of this shorthand, and I defer (no pun intended) to your better judgement! |
@ndkrempel writes
Is it? I don't know one way or the other and would appreciate any evidence. Thanks. What about existing languages with await, like C#? Do they have any equivalent to an await all? If not, does their manual pattern equivalent to our "yield Q.all([...])" appear a lot? What fraction of all await statements? |
@ndkrempel |
@domenic Even the first two cases you illustrate are not equivalent if the latter promises reject before the first resolves. |
@erights But agree that the shorthand applies to the output as well as the input (if you used the shorthand |
What would you do with the array of resolved promises typically anyway? I would guess, pattern match it against an array pattern of variable definitions. In ES6:
If we're thinking about ES7 sugared syntax, "await all" still leaves the variables distant from their initializing expressions. How about
? |
@erights The C# equivalent seems to be |
@ndkrempel |
@erights Some quick figures... Google search for "C#" "await": 351,000 results. Ohloh code search for "await" (limited to C#): 6,008 results. Bear in mind that many users are inadvertently (or because they don't care about performance) serialising their code with It seems to me that it is common because it is necessary whenever you have a parallel fork point (e.g. waiting on multiple async operations), but without the annoyance of having to introduce a local variable solely to kick-off an async operation: var p1 = asyncOp1(), p2 = asyncOp2(), p3 = asyncOp3();
var v1 = yield p1, v2 = yield p2, v3 = yield p3; ...is a bit too long-winded! |
const [v1, v2, v3] = yield Q.all([op1(), op2(), op3()]); Isn't |
Given the numbers, i do not like the proposed change. The implicit cast is consistent with other promise patterns. Switching behaviors on an array test isn't, and is surprising. |
@erights I would say it is, although more specifically the problem there is the line-noise aspect. Compare: const [v1, v2, v3] = yield [op1(), op2(), op3()]; I admit that if |
@erights As for the implicit cast, see @petkaantonov's comments. I think |
@ndkrempel Returning non-promise values from then-handlers, and passing non-promise values to @jlongster asked for this feature some time ago. Although I wanted to make him happy then, and to make @ndkrempel happy now, I think that I will stand by the status quo. Explicit is better than implicit, at least in this case, and consistency is better than a dweomer, in the Perl sense, especially when it folds semantics in ways that are difficult to unfold. |
Within a
Q.async
ed function, could we allow:as a convenient short-hand for:
It seems like this is a very common operation and the proposed new syntax is intuitive and reduces line-noise considerably.
Technically, this would be backwards-incompatible as currently within a
Q.async
ed function, you can usex = yield y;
for a non-promise valuey
and the value will pass through unchanged (after some hoops and jumps) tox
. I'm not sure anyone does this however.The text was updated successfully, but these errors were encountered: