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

Jacob Bloom mr.jacob.bloom at gmail.com
Wed Nov 20 05:29:31 UTC 2019


Regarding the other `Promise` methods, this syntax could certainly
extend to all of them (that's part of the reason I chose this syntax,
to leave that option open).

`await.any` and `await.race` would work analogously to `await.all`,
but since we're no longer dealing with return values there's no good
way to get the value that won the race. This is fine as long as you're
not dependent on that value and only care about executing some code as
soon as the race is won. The best way I can think of to get the
winning value is something like this:

```javascript
async function myFunc() {
  let value1, value2;
  await.any {
    value1 = await foo;
    value2 = await bar;
  }
  const firstResult = value1 || value2; // could also use ??
}
```

...which isn't any easier than using `Promise.any`.

`await.allSettled` would, in many cases, be the same as `Promise.all`
except it would also swallow errors. I'd have to think more about its
use cases but it could be implemented the same way.

On Tue, Nov 19, 2019 at 9:20 PM 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


More information about the es-discuss mailing list