Proposal: `await.all {...}` for parallelism

Naveen Chawla naveen.chwl at gmail.com
Tue Nov 26 14:47:56 UTC 2019


If I have, as per your examples,

x1 = await||actionAsync1()
x2 = await||actionAsync2(x1) //x1 is undefined here, only resolved on the
next "non-parallel-await"

vs adding a line between the two calls:

x1 = await||actionAsync1()
let c;
x2 = await||actionAsync2(x1)

...does the `let c` automatically break the parallel grouping since it's a
non-parallel operation (thereby making x1 defined)?

It seems to me like you are doing block logic without blocks, which I think
increases the chances of bugs. Also you're not leveraging the existing
parallel execution pattern for async functions (which is just to omit the
`await`), so it would seem you would be increasing learning overhead. And,
you're not really allowing for submitting more sophisticated mixtures of
serial async, parallel async and synchronous code for "parallel completion"
guarantee, by requiring that parallel calls be "grouped" together in terms
of lines of code, almost allowing for nothing beyond the current
"Promise.all" pattern, logically. I don't think this is satisfying the
original motivation.

For a `awail.all { ... }` block, maybe allowing a "return"/"yield" value
could neaten up the block scope separation, but maybe that could be left to
the "do" expression if that were adopted. But I don't think it's a big
sacrifice if neither exist.


On Tue, 26 Nov 2019 at 14:14, manuelbarzi <manuelbarzi at gmail.com> wrote:

>
> OK I'm even more confused now. x1 is surely not a resolved value until all
>> the next "non parallel await" so is it "undefined" until then?
>>
>
> as a `const` x1 does not exist until those parallel awaits `await||` (for
> p1 and p3) are resolved (same for x3). then p2 is resolved after that.
>
> what it tries to bring is a simplification of syntax.
>
> Could you give an example of what you mean by the `await.all { ... }`
>> block syntax bringing "complexity on returning values assignment,
>> specially when" "about constants (`const`)", as I'm unclear what you are
>> referring to
>>
>
> `const` and `let` are block-scoped, so this is referring to avoid that
> block notation, and then keep coherent with the possibility to directly
> infer in current scope references without extra segments / blocks.
>
>
>> On Tue, 26 Nov 2019 at 13:35, manuelbarzi <manuelbarzi at gmail.com> wrote:
>>
>>>
>>>
>>>> Why not just maximally preserve current JavaScript for parallel
>>>> execution, just by omitting `await` in multiple async calls, simply
>>>> wrapping it in an `await.all` block to ensure completion before code
>>>> continues past the block. This surely is the more straightforward way to
>>>> satisfy the same goals?
>>>>
>>>
>>> because wrapping it an `await.all` on the one hand explicitly groups
>>> promises, but brings complexity on returning values assignment, specially
>>> when is about constants (`const`). so, if you avoid blocks, just marking
>>> parallel awaits with, for example, a suffix `await||`, or whatever other
>>> more convenient way, you can just write the code in series as normally, and
>>> avoid that complexity. the transpiler would just require to group the
>>> consecutive marked parallel awaits (`await||`) into a Promise.all() and
>>> that's it. following i reproduce the demo before:
>>>
>>> ```
>>> // NOTE p? = function call that returns a promise (? = just and index)
>>>
>>> // NOTE s? = function call that runs synchronously and returns a value (? = just and index)
>>>
>>> const x0 = await p0()
>>>
>>> const x11 = s11() // sync code in-the-middle
>>>
>>> const x1 = await || p1(x0)
>>> const x3 = await || p3(x11)
>>> const x2 = await p2(x1)
>>> const x10 = await p10(x2, x3)
>>>
>>> const x12 = s12() // sync code in-the-middle
>>>
>>> const x4 = await || p4(x1, x2)
>>> const x5 = await || p5(x2, x3, x12)
>>> const x6 = await p6(x4, x5, x10)
>>>
>>> const x7 = await || p7(x4, x6)
>>> const x9 = await || p9(x5, x6)
>>> const x8 = await p8(x6, x7)
>>>
>>> await p11(x8, x9)
>>>
>>>
>>> // it would resolve a tree of parallel and series like following with traditional promises
>>>
>>> p0
>>>     .then(x0 => {
>>>         const x11 = f11()
>>>
>>>         return Promise.all([p1(x0), p3(x11)])
>>>             .then((x1, x3) =>
>>>                 p2(x1)
>>>                     .then(x2 =>
>>>                         p10(x2, x3)
>>>                             .then(x10 => {
>>>                                 const x12 = s12()
>>>
>>>                                 return Promise.all([p4(x1, x2), p5(x2,
>>> x3, x12)])
>>>                                     .then((x4, x5) =>
>>>                                         p6(x4, x5, x10)
>>>                                             .then(x6 => Promise.all([p7(
>>> x4, x6), p9(x5, x6)])
>>>                                                 .then((x7, x9) => p8(x6
>>> , x7)
>>>                                                     .then(x8 => p11(x8,
>>> x9))
>>>                                                 )
>>>                                             )
>>>                                     )
>>>                             })
>>>                     )
>>>             )
>>>     })
>>> ```
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20191126/0ea2831e/attachment-0001.html>


More information about the es-discuss mailing list