async/await improvements

James Long longster at gmail.com
Tue Nov 11 22:33:44 PST 2014


After a brief twitter conversation last night
(https://twitter.com/lbljeffmo/status/532402141001179136) I thought
I'd post some thoughts I've been having about async/await.

I feel like I'm about to walk into a pit where people throw lava at
each other, but I need to see if at least a few other people agree
with me.

I know I'm in the minority here, but I don't like promises behavior of
automatically suppressing all errors. But I know there advantages to
it. Pros & cons, you know. However, recently there's been talk of
adding special builtin `async` and `await` features to ES7. This is
cool, except that currently they are built on top of promises, meaning
you get the same suppress-error-by-default behavior.

Meaning, if I had the following:

async function foo() {
  throw new Error('bad');
}

You wouldn't see this error unless you remember to somehow "end" the
async chain. Am I correct in this?

The thing is, I think we actually have a chance to fix this since
async/await will be special builtin syntax. Let's first take a look at
C# error handling behavior (which supposedly is what inspired
async/await):

async static void AsyncVersion() {
   // uh oh error happened
}

The above code throws the error by default, no special handling
needed. Isn't that cool? But what if you want to handle errors
asynchronously? Well, C# knows that you don't return anything above,
so it knows if can just throw it. If you want to forward the error,
you need to return a Task:

async static Task AsyncVersion() {
  // throw an error
}

So there's actually 2 different ways to suggest how to forward/throw
errors. This makes async/await insanely cool because you know at some
point at the top of chain the error will always throw, since you will
always be calling it from a top-level void async function.

Can't we do the same with our async/await? What if we made it only
possible to call async functions from other async functions, made
`async function` throw by default (not forward), but introduced
`async^` which would forward?

async^ function foo() {
  // errors here are captured and forwarded
}

async function foo() {
  // errors here are thrown in the JS processes
}

This makes it the default behavior to be "forgot to forward error"
instead of "forgot to log the error", which is better imho. I'm sure
there are problems with this, and the community might hate it. If so
please let's just move on and not make this a holy war. I can accept
that the JS community has already embraced promises-style error
handling. But I thought I'd throw this quick idea out there.

With <3,
- James


More information about the es-discuss mailing list