await on synchronous functions

Tom Van Cutsem at
Wed Aug 5 06:41:48 UTC 2015

2015-07-27 5:42 GMT+02:00 Dean Landolt <dean at>:

> On Sun, Jul 26, 2015 at 8:07 AM, Benjamin Gruenbaum <benjamingr at>
> wrote:
>> > Out of curiosity, can you give an example of the Not Good parts? ISTM
>> the await prefix is more of an explicit cast than an implicit conversation,
>> and other than the very small timing gap in how throws are handled I
>> pointed out a few days ago, I can't think of any situations where a throw
>> would make more sense than casting values to promises.
>> Sure, lots of such cases exist today with promises and are easy to
>> reproduce
>> ```js
>> async function foo {
>>     let result = await bar; // instead of bar();
>>     let result2 = await callbackFn(); // await on function that was not
>> "promisified yet", that is, it takes a callback
>>     let result3 = await [p1, p2, p3]; // people might expect a
>> Promise.all on an array, but this doesn't actually wait for anything.
>> }
>> ```
> The first example is a basic type error, not at all specific to promises
> or async programming -- it could be made any number of ways. If you want to
> call it a footgun, that's fine -- but ISTM the only real solution is "use
> TypeScript" (or some analog).
> I don't see how the last example could possibly exist today as it reflects
> a hypothetical user's misunderstanding of `async/await` syntax
> specifically. Perhaps there's a case to be made that there's a footgun here
> (though I'd disagree), but it's beside the point of this thread.

I recently found out that a popular async cflow library for node based on
generators, co <> does allow one to "await" (yield)
an array, with the semantics that Benjamin alluded to (Promise.all
synchronization). At least it indicates that this is not a totally
unrealistic expectation on behalf of users. Personally I think
automatically Promise.all'ing arrays is a bit too implicit, but I can
understand why people find it appealing.

> But the second example, `await callbackFn()`, seems reasonable. I still
> think it would be a shame to punt on otherwise elegant ergonomics just due
> to this, but I buy that there's at least some benefit now.

Speaking from experience with a programming language I was involved with
called AmbientTalk, which has JS-style Promises, we did run into this issue
and we had a pragmatic way of solving it. Translated into the context of
this discussion, what we specified is that `await undefined` would raise a
runtime error, while `await any-non-promise-value` would coerce the
non-promise value into a resolved promise and await that promise instead.

At first sight, it might feel awkward for `await` to special-case
`undefined`, but given that it is JS's implicit return value, I suspect it
would catch a lot of errors of the type Benjamin described above. It's a
pragmatic way of dodging the footgun without completely breaking the
symmetry between await and Promise.resolve.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list