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

Cyril Auburtin cyril.auburtin at gmail.com
Wed Nov 20 09:05:57 UTC 2019


There's `for await` loops since recently, there could be `await for` loops
for wrapping the whole execution of a loop

```js
console.time(1);
await for (const fn of [()=>delay(50).then(()=>'a'),
()=>delay(80).then(()=>'b')]) {
  console.timeLog(1, await fn());
}
console.timeEnd(1);
```

This would log the same than:

```js
console.time(1);
await Promise.all(
  [()=>delay(50).then(()=>'a'), ()=>delay(80).then(()=>'b')]
    .map(async fn => { console.timeLog(1, await fn()) })
);
console.timeEnd(1);
/*
1: 51.066162109375ms a
1: 80.998291015625ms b
1: 81.315185546875ms
*/
```

without `await for`, things are serial:
```js
console.time(1);
for (const fn of [()=>delay(50).then(()=>'a'),
()=>delay(80).then(()=>'b')]) {
  console.timeLog(1, await fn());
}
console.timeEnd(1);
/*
1: 50.68212890625ms a
1: 130.9951171875ms b
1: 131.1162109375ms
*/
```

(`var delay = t => new Promise(r => setTimeout(r, t));`)

On Wed, Nov 20, 2019 at 6:44 AM Jacob Bloom <mr.jacob.bloom at gmail.com>
wrote:

> Regarding parallel for-loops: I'd consider that a separate problem.
> You'd want parallel for-loops for things like requests to the same
> API, where each promise is handled the same way. `await.all` is more
> for handling disparate tasks in parallel without having to resort to
> thinking in terms of arrays and iteration.
>
> On Tue, Nov 19, 2019 at 10:27 PM Guy Bedford <guybedford at gmail.com> wrote:
> >
> > Typically I find I want to loop over an iterator of items and apply a
> function body of work on them in parallel.
> >
> > So it would be nice to support full blocks of statements that can do
> this work in parallel, instead of relying on just expressions or functions
> to achieve this.
> >
> > Extending for loops to have a parallel form is another option (I seem to
> recall something similar brought up before here):
> >
> > ```
> > for await.all (const entry of entries) {
> >   await doWork(entry);
> > }
> > ```
> >
> > Whether async iteration should be supported or treated as sync or
> parallel is another question though, and possibly a confusion of the form.
> >
> > On Tue, 19 Nov 2019 at 23:20, Jordan Harband <ljharb at gmail.com> wrote:
> >>
> >> If we have `await.all`, what about `await.race`, `await.allSettled`,
> `await.any`?
> >>
> >> On Tue, Nov 19, 2019 at 7:45 PM Jacob Bloom <mr.jacob.bloom at gmail.com>
> wrote:
> >>>
> >>> To simplify the problem of working with promises in parallel, I
> >>> propose this new syntax:
> >>>
> >>> ```javascript
> >>> async function initialize() {
> >>>   let foo, bar, baz;
> >>>   await.all {
> >>>     foo = (await request('foo.json')).data;
> >>>     bar = (await request('bar.json')).data;
> >>>     baz = (await request('baz.json')).data;
> >>>   }
> >>>   render(foo, bar, baz);
> >>> }
> >>> ```
> >>>
> >>> Each child statement of the curly braces is evaluated in parallel and
> >>> execution resumes when they've all resolved.
> >>>
> >>> **The Problem:** with current syntax, the above function would
> >>> probably look something like this:
> >>>
> >>> ```javascript
> >>> async function initialize() {
> >>>   const [
> >>>     { data: foo }, // renaming response.data => foo
> >>>     { data: bar },
> >>>     { data: baz },
> >>>   ] = await Promise.all([
> >>>     request('foo.json'),
> >>>     request('bar.json'),
> >>>     request('baz.json'),
> >>>   ]);
> >>>   render(foo, bar, baz);
> >>> }
> >>> ```
> >>>
> >>> For this kind of use case, `Promise.all` leads to "parallel lists" of
> >>> promises and their return values, which must be kept in sync. Using
> >>> those values either requires (sometimes deep) destructuring or
> >>> temporary variables.
> >>>
> >>> This structure is also just fundamentally different from working
> >>> serially in async/await and it forces you to reason about the problem
> >>> in a specific way. This doesn't appear to be a conscious decision to
> >>> force good code practices, it's just a limitation that falls naturally
> >>> out of the current syntax. Thus, we have an opportunity to shift some
> >>> of the burden back to the language with this new syntax.
> >>>
> >>> Here's the full proposal:
> >>> https://github.com/mrjacobbloom/proposal-await-all -- let me know what
> >>> you think!
> >>> _______________________________________________
> >>> es-discuss mailing list
> >>> es-discuss at mozilla.org
> >>> https://mail.mozilla.org/listinfo/es-discuss
> >>
> >> _______________________________________________
> >> es-discuss mailing list
> >> es-discuss at mozilla.org
> >> https://mail.mozilla.org/listinfo/es-discuss
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20191120/d33ddda5/attachment-0001.html>


More information about the es-discuss mailing list