Re: Would it be possible to add “await on first use” to the language?

Šime Vidas sime.vidas at
Fri Feb 24 18:35:08 UTC 2017

> Domenic's version using current `async`/`await` syntax is nice and clear
> (one might tweak the variable names a bit to differentiate promises from
> resolved values, but...).

This is the issue I have with this approach. The author is forced to create
two sets of variables (for promises and resolved values), depending on the
structure of the concurrent tasks. I think this is micromanagement. If the
language can resolve us of this, I think that’s a convenience worth having.

> Separately, I think you're going to run into implementational complexity.
> These automatic-`await` values are neither promises nor resolved values,
> they're a new beast with hidden `await` behavior; call them "hidden
> promises." Within an `async` function, most but not all [GetValue][1]
> operations on the variables/properties containing these hidden promises
> would need an "if this is a hidden promise, `await` it" guard: Any math
> operation, any string operation, any object operation, any time an `async`
> function passes the value into a non-`async` function, etc. Just about the
> only exception would be assignment (well, most assignments; more below),
> which would just copy the hidden promise. This becomes particularly
> problematic when you think about what it means to have one of these within
> a structure, like an array or object; what if we then pass its container to
> a non-`async` function? Do we recursively search the container for
> automatic-`await` values and `await` them before calling the non-`async`
> function? In what order? Similarly, the return values of `async` functions
> would need vetting, but (arguably) only if being returned to non-`async`
> functions, which makes for some new layer between caller and callee or an
> uncomfortable awareness in the `async` function of where its return value
> is going. Handling all of that sounds like a lot of runtime cost to simply
> hide `await` from ourselves. And updating all of this in existing engines
> seems like a lot of work.

I’m not sure why it would need to be that complicated. These lazy-await
variables would resolve to a value on first use, in any context (first use
= first appearance of the variable in the code). With that logic, the
variables could be treated as resolved values (i.e. the author would view
them as values, not promises) - it’s just that they’re lazy-resolved, so
instead of blocking early, they block late, allowing multiple concurrent
tasks to be kicked off at the beginning of the async function, without
having to micromanage their promises. That’s the key, I think - the
benefits of concurrent tasks without the burden of managing promises.

> Finally, there's the educational cost of explaining what triggers a hidden
> `await` to new JavaScripters.
> I can imagine a new inherently-async language with this sort of thing at
> its core (probably without non-`async` functions at all, avoiding a lot of
> the complexity above; instead making async-until-the-last-second the
> default with an explicit "resolve"). It could well be quite interesting.
> But for JavaScript, I think we're better off with the explicit `await`.

In case it’s not clear, this wouldn’t change how await works or be a
replacement of it. Await is great, especially for sequential async
operations. So, everyone, continue using explicit await. But this new
‘lazy-await variable’ would enable new code patterns - it would allow us to
*get multiple async values in parallel*, without having to micromanage
their promises. I think, there’s a real value here.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list