Does async/await solve a real problem?

Florian Bösch pyalot at
Thu Sep 11 06:20:15 PDT 2014

await has also another problem in that if somewhere, deep down the call
stack, something is intending to do async, then up the entire call stack
everywhere you've got to insert await. It's a bit of a headache for code
maintenance (hello bicycle repair man jam session), and it's also fairly
unfriendly for library authors.

There is a solution to that problem, which is not using generators if you'd
want co-routines. If you want co-routine like behavior, please implement
co-routines (and you can prop whatever scheduling/managing on top of that).

An argument has been made in earlier discussions on that topic, that JS VMs
can't deal with co-routines (garbage collection, DOM, whatever). But
surely, if the VM can support generators/continuations, it could support
full co-routines.

I'd recommend python's greenlet as an outstanding implementation of a
co-routine interface that includes basically everything one could wish from
it. I'd not consider python 3's "asyncio" a proper co-routine
implementation (i.e. it's the same generator/await hack as is being
discussed here).

On Thu, Sep 11, 2014 at 3:05 PM, Kevin Smith <zenparsing at> wrote:

> Also, see
> for previous discussion.
> On Thu, Sep 11, 2014 at 8:42 AM, Domenic Denicola <
> domenic at> wrote:
>> There are several problems solved by async/await instead of twisting
>> generators:
>> 1. What if you wanted to use generators for lazy sequences (iterables),
>> instead of asynchronicity? If your framework assumes all generators are for
>> async, you lose the original use case of generators.
>> 2. Say what you mean. `function*` and `yield` mean something very
>> different from `async function` and `await`, similar to how
>> `Subclass.prototype = Object.create(Superclass.prototype);
>> Subclass.prototype.constructor = Subclass` is different from `class
>> Subclass extends Superclass`.
>> 3. Operator precedence. You can do `await a + await b` to mean `(await a)
>> + (await b)`, but `yield a + yield b` means `yield (a + (yield b))`.
>> 4. Ability to produce promise-returning functions without buying into a
>> specific framework that interprets generators in a certain way. E.g., you
>> could use `async function f() { return 5; }` to return a promise for 5,
>> which people can consume with `f().then(v => ...)`. If you try to do
>> `function* f() { return 5; }` you will get an iterable, which is not
>> understood to be asynchronous. (Hopefully my use of `return 5` for brevity
>> instead of more complex code does not confuse this point for you.)
>> As for stack traces, long stack trace support is a debugging feature, and
>> the fact that `yield*` gets them right now doesn't mean that `await` won't
>> get them in the future.
>> -----Original Message-----
>> From: es-discuss [mailto:es-discuss-bounces at] On Behalf Of
>> Jeswin Kumar
>> Sent: Thursday, September 11, 2014 11:46
>> To: es-discuss at
>> Subject: Does async/await solve a real problem?
>> Looking at my project (in which asynchronous calls are entirely done via
>> generators), I can't see how async/await would simplify code for end-users
>> like me (application programmers).
>> End users write the spawn()/Q.async()/co() wrapper *at most* one single
>> time in an application:
>> 1. When using a framework like say koajs, you don't have to write it even
>> once.
>> 2. While not using a framework, you'd have to use the wrapper one single
>> time in say, the main.js file.
>> To use the example at
>> async function chainAnimationsAsync(elem, animations) { CODE; } is just
>> function chainAnimationsAsync*(elem, animations) { same CODE; } when flow
>> control is done by a framework or at the entry point to your application.
>> spawn() isn't needed.
>> I can't see how this will reduce application's code even a little. So my
>> question is, is async/await needed?
>> One more question
>> --------------------------
>> 1. yield is practically very difficult to use in a project because you
>> don't get proper stack traces (at least with the current flow control
>> libraries). You'd only see the last call which threw the error, and then
>> functions from the flow control library immediately below that. I suppose
>> the generators leading up to the erring generator are all suspended and
>> wouldn't be on the stack frame chain.
>> 2. yield* generator delegation solves this problem, you get real stack
>> traces. I was able to get full stack traces simply by replacing all yield
>> X() with yield* X()
>> example code as in:
>> So if there are valid use-cases for adding async/await to JS, shouldn't
>> it be based on how yield* works rather than yield?
>> -- Jes
>> The Fora Project is coming...
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list