Does async/await solve a real problem?

Domenic Denicola domenic at
Thu Sep 11 05:42:08 PDT 2014

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

More information about the es-discuss mailing list