Does async/await solve a real problem?

Bruno Jouhier bjouhier at
Thu Sep 11 23:48:37 PDT 2014

>  Arguably, the fact that a function may suspend in mid-flight should be
> part of its documentation (i.e. function signature), as it directly affects
> the caller.

It does. With async/await the function signature must be marked with
'async' if the function body contains 'await'.

> As an analogy, consider `IO` in Haskell: if you have this large piece of
> purely functional code, and deep down you're all of a sudden introducing
> mutable state, you will need to refactor the larger piece of code to reveal
> that it in fact performs IO as well.

> While this refactoring may be tedious (no disagreement there), it forces
> you to review all affected code, which is good, because the dependencies of
> that code may have changed (i.e. side-effect the client previously thought
> would execute atomically may now no longer be atomic).

It is tedious but not error prone. The compiler will tell you if you did
anything wrong.

In a large project, high level code tends to be async anyway because there
is always some async code (from which you need a result) like a database
operation, a web service call, a file access, etc. underneath. Low level
code is usually a mix of tight algorithms written in sync style and low
level I/O written in async style. So the refactoring, when it happens, is
usually contained to one algorithm, as the high level code is already
written in async style.

Refactoring sync code into async is completely straightforwards with
async/await. it is just a matter of adding async/await keywords. Without
async/await you have to restructure the code with callbacks or promises
which is a very different story: complex and error prone.

Also, an observation on explicit markers: these markers are very useful in
low level I/O handling code because they let you clearly see the boundaries
of the atomic sequences. In high level code, they are less important
because the concurrency problems should be addressed at the low level and
the high level code usually deals with data which is specific to a request
and which is not shared with other requests.

When working with async/await you will also need a library function that
lets you protect critical sections containing await markers. In our
library, we do it with a funnel:

var fun = createFunnel(1);

async function foo() {
  var zoo = await fun(async function() {
    // critical section containing await directives

Funnels can also be used to limit the level of concurrency (fun =
flows.funnel(max)). This is a very simple way to avoid resource exhaustion
in high concurrency scenarios.

> Cheers,
> Tom
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list