Inspired by #2321, this is an idea for performing "parallel" asynchronous computations in async functions.
Rather than doing parallel awaits on futures, this feature allows separate asynchronous expressions to be evaluated in parallel (interleaved) rather than sequentially. Each expression can contain one or more awaits.
Example syntax:
await*(e1, e2, e3)
This is an expression, theawait* must be followed by a parenthesized, comma-separated (trailing comma allowed) list of expressions.
If the static type of e1 is T1, etc., the static type of await*(e1, e2, e3) is (T1, T2, T3), just as it would be without the await*.
The difference is that when e1 hits its first asynchronous supension (if any), rather than suspending the entire method body, evaluation proceeds to evaluation of e2 and then e3. The initial, synchronous, part of the computation of e1, e2 and e3 happens synchronously, then each computation can continue when its await completes, until its next await.
When all (three here) expressions have computed a value, the await* expression completes with a record of those values.
If any of the expressions completes by throwing, so will the await* expression, but not until all expressions have completed.
The error thrown, perhaps a ParalleleAwaitError, will contain a tuple of the same width as the expected result, with the successful values on their corresponding positions, and null in the positions of the expressions which threw, as well as a collection of the errors in some form.
You can nest await*, but you have to do it explicitly:
var result = await*(e1, e2, await*(e3, e4));
This will evaluate e1, e2, e3 and e4 in parallel.
This differs from what you can write using existing Dart, since it doesn't just expect a Future at each position.
Instead it allows an asynchronous computation in the current scope. It's basically a call-by-name parallel await function where each expression acts like it computes to a future, but without actually needing to do that.
If you want to await several heterogeneously typed futures, you can do so as var (v1, v2, v3) = await*(await f1, await f2, await f3);.
Inspired by #2321, this is an idea for performing "parallel" asynchronous computations in
async
functions.Rather than doing parallel
await
s on futures, this feature allows separate asynchronous expressions to be evaluated in parallel (interleaved) rather than sequentially. Each expression can contain one or moreawait
s.Example syntax:
This is an expression, the
await*
must be followed by a parenthesized, comma-separated (trailing comma allowed) list of expressions.If the static type of
e1
isT1
, etc., the static type ofawait*(e1, e2, e3)
is(T1, T2, T3)
, just as it would be without theawait*
.The difference is that when
e1
hits its first asynchronous supension (if any), rather than suspending the entire method body, evaluation proceeds to evaluation ofe2
and thene3
. The initial, synchronous, part of the computation ofe1
,e2
ande3
happens synchronously, then each computation can continue when itsawait
completes, until its nextawait
. When all (three here) expressions have computed a value, theawait*
expression completes with a record of those values.If any of the expressions completes by throwing, so will the
await*
expression, but not until all expressions have completed. The error thrown, perhaps aParalleleAwaitError
, will contain a tuple of the same width as the expected result, with the successful values on their corresponding positions, andnull
in the positions of the expressions which threw, as well as a collection of the errors in some form.You can nest
await*
, but you have to do it explicitly:This will evaluate e1, e2, e3 and e4 in parallel.
This differs from what you can write using existing Dart, since it doesn't just expect a
Future
at each position. Instead it allows an asynchronous computation in the current scope. It's basically a call-by-name parallelawait
function where each expression acts like it computes to a future, but without actually needing to do that.If you want to await several heterogeneously typed futures, you can do so as
var (v1, v2, v3) = await*(await f1, await f2, await f3);
.