
JavaScript async/await implemented in V8 - onestone
https://chromium.googlesource.com/v8/v8.git/+/d08c0304c5779223d6c468373af4815ec3ccdb84
======
tanto
The moment I started using async await (with babel) combined with the new
fetch API so many libraries got obsolete.

Getting data is as easy as:

    
    
      async function main () {
        try {
          const res = await fetch('https://api.github.com/orgs/facebook');
          const json = await res.json();
          console.log(json);
        } catch (e) {
          // handle error
        }  
      }
    

So I am quite happy when this lands in modern browsers asap.

~~~
startling
Is the syntax composable? Can I do

    
    
        const json = await (await fetch(https://api.github.com/orgs/facebook')).json();
    

or do I have to name it?

~~~
smilekzs
What you asked for is whether `await` is idempotent. No it isn't. The
"argument" to `await` is a Promise, and the "return value" of it is the
resolved _value_ of the Promise (i.e. `Promise#then`).

EDIT: I missed the `.json()` part, but I suppose it doesn't return a Promise,
no?

~~~
tanto
actually .json() returns a Promise. The first fetch only returns HTTP status
code and some other details. The content itself is streamed. You can also
access the stream if you want too. In general you would rather just call
.json() and get the parsed data.

The fetch function can for example also be used to get images. There you would
use .blob() and assign that to an image.src with URL.createObjectURL(blob);

See here: [https://developer.mozilla.org/en-
US/docs/Web/API/Fetch_API/U...](https://developer.mozilla.org/en-
US/docs/Web/API/Fetch_API/Using_Fetch)

------
bigtones
Thank you to Microsoft and Anders Hejlsberg for inventing Async/Await (and to
F# for the original inspiration)
[https://en.wikipedia.org/wiki/Futures_and_promises](https://en.wikipedia.org/wiki/Futures_and_promises)

~~~
Lx1oG-AWb6h_ZG0
async/await as we know it actually came from Midori's C# dialect, which indeed
was inspired from F#: [http://joeduffyblog.com/2015/11/19/asynchronous-
everything/](http://joeduffyblog.com/2015/11/19/asynchronous-everything/)

(Although, just to be pedantic, the concept of futures is way older than F#.
Alice's syntax, for example, is pretty close)

~~~
MichaelGG
The nice part about F#'s async implementation is that it was purely a library.
I wish languages aimed at allowing developers to build things for the
language, rather than providing more compiler built-ins. Making it extensible
is more elegant (though I understand it might be easier to optimize perf).

~~~
barrkel
Integrated features are easier to tool and provide good diagnostics for. It's
nice to have enough expressiveness to model monadic computations without too
much syntactic overhead - and monads are usually enough, since they hand blobs
of user code to the library to be composed as necessary - but debugging a
reshuffled graph of closures is no picnic.

------
hoodoof
This news is almost as important as the rest of ES2015 being implemented in
Webkit.

async/await is the final piece in the puzzle of providing real solutions to
callback hell in JavaScript.

~~~
ihsw
I am willing to admit that async/await is a bridge between the Node and .Net
communities -- surmounting this means we are that much closer to literally
doubling the developer pool for either sections of the community.

~~~
mkoryak
how so? I like the JS async/await a lot, but you couldnt pay me to write .net

I personally don't know many devs who would choose to learn a new lang because
of a feature (assuming that they didn't want to learn it before it existed)

~~~
egeozcan
I don't understand. I also like JS async/await and like JS and node in general
but .NET is simply beautiful IMHO (given you are using F# or C#). Why would
you rather not write .NET code?

~~~
189723598
c# is a great language but many people don't want to have to specify type
information so often or create classes so often. Even many statically-typed
languages don't require as much List<T> stuff. Also, everything outside of the
language itself sucks. The frameworks, the operating system is has to run on,
the community, etc.

~~~
Sir_Cmpwn
I object to this. The .NET Framework is top tier and sets a high bar for
standard libraries, in my opinion. It also runs on any OS just fine,
especially now that Microsoft's own implementation is open source and MIT
licensed. The community is also very strong with tons of docs and libraries
and SO Q&As and plenty of jobs and local user groups. And if you don't like
the C# boilerplate, F# has all of the same benefits.

Enough with the FUD around .NET/C#, I'm a full time Linux greybeard and even
I'm sick of it.

------
dmihal
Here's a simple guide to async/await.

[https://www.twilio.com/blog/2015/10/asyncawait-the-hero-
java...](https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-
deserved.html)

~~~
sotojuan
Eddie Zaneski is an awesome and friendly guy!

Here's another awesome article on it:

[http://amasad.me/2015/10/31/javascript-async-functions-
for-e...](http://amasad.me/2015/10/31/javascript-async-functions-for-easier-
concurrent-programming/)

------
ch49
Why is "async" keyword needed? Can't JS engine infer from the use of "await"
in a function that this function need to be async? I'm using async/await for a
while now, and so many times I've introduced bugs in my code because i forget
to put "async" in front of the function, or put "async" in front of wrong
function. It's simply annoying to go back and put "async" when in middle of
writing a function I realise I need to use await.

~~~
ilkkao
Reason is mentioned here: [https://github.com/tc39/ecmascript-
asyncawait/issues/88#issu...](https://github.com/tc39/ecmascript-
asyncawait/issues/88#issuecomment-181517500)

~~~
mstade
Thanks for this! Also later in that thread is an example to further bring home
the point: [https://github.com/tc39/ecmascript-
asyncawait/issues/88#issu...](https://github.com/tc39/ecmascript-
asyncawait/issues/88#issuecomment-181574985)

Solid reasoning, in my opinion.

------
md224
Looking at Kangax's support table:

[http://kangax.github.io/compat-table/esnext/#test-
async_func...](http://kangax.github.io/compat-table/esnext/#test-
async_functions)

Apparently Microsoft Edge seems to have been the first browser to implement
it... good job Microsoft!

------
andrewstuart2
I have yet to see a convincing argument that this feature is necessary or even
helpful beyond one-liners. The Q promises API, to me, is the right way to
reason about asynchrony. Once you understand closures and first class
functions, so much about complex asynchronous flows (e.g. multiple concurrent
calls via Q.all, multiple "returns" via callback arguments) become so simple.
The "tons of libraries" argument doesn't make tons of sense either. I've done
a lot of async and I've never needed anything beyond Q that I can recall.

This feels like a step toward added confusion rather than language unity. Much
like the majority of of ES6 feels to me: bolted-on features from popular
synchronous languages that themselves are only now adding features like
lambdas.

I don't want to write faux-event-driven code that hides the eventedness
beneath native abstractions. And I definitely don't want to work with
developers, new and old, trying to learn the language and whether/when they
should use async/await, promises, or fall back to an es5 library or on* event
handlers. I want developers who grok functional event-driven code with
contextual closures.

~~~
brandonbloom
Allow me to make both a theoretical and practical argument.

It's been said that "callbacks are imperative; promises are functional". It's
true. Furthermore, callbacks structure control flow and promises structure
data flow. Instruction scheduling is an explicit sequence with callbacks
(well, assuming the API calls you back precisely once), but scheduling is an
implicit topological sort of the directed acyclic dependency graph of
promises.

Sometimes, when it comes to side effects, implicit scheduling is less than
ideal. You need specific things to happen in a specific order. The solution is
to introduce data dependencies to force a particular schedule. This is
precisely what is done by monads in Haskell. However, unlike Haskell,
JavaScript doesn't have "do" syntax, so there's no convenient notation for a
nested chain of bindings.

The result of not having monadic binding syntax is that you wind up with some
funky nested chain of getY(x).then(y => y.then(z => z.then(.... OR you have to
declare variables up top, flatten your then blocks in to a promise chain, and
often ignore intermediate values:

    
    
        let y, z;
        getY(x)
        .then(returnedY => { y = returnedY; return zPromise(); )
        .then(returnedZ => { z = returnedZ; return ......; }
        .then(......another side effect.....)
        .then(_ => f(y, z))
    

async/await neatly eliminates this problem by reusing the traditional coupling
of data flow dependencies with first-order control flow dependencies.

Practically:

    
    
        let y = await getY(x);
        let z = await getZ(y);
        ......another side effect....
        return f(y, z)

~~~
andrewstuart2
> It's been said that "callbacks are imperative; promises are functional".
> It's true. Furthermore, callbacks structure control flow and promises
> structure data flow.

Do you have any good escapes l examples of further reading on this? I'm not
sure I agree with this statement, or perhaps don't fully understand it. It
seems like both cases boil down to functions as data (function pointers
essentially) that are called at the end of some event or chain of events.

To me, they seem to be the exact same thing but worth promises being much more
human readable.

~~~
brandonbloom
You can google that quote and find more, but the control flow vs data flow
formulation is not widely discussed from what I've seen.

~~~
tel
It's widely discussed in Haskell communities, fwiw ;)

------
ht85
Kinf of OT, but can anyone share their experience about using Babel's
async/await in production instead of regular Promises?

I'd love to hear about people who have used it in large and complex projects,
from a debugging standpoint.

As of now, using Bluebird (with its source in a different, blackboxed script),
it is possible to follow the code execution through the event loop with async
debugging, in a very elegant and enjoyable fashion.

I find async/await much more appealing when coding, but I'm worried about
quality of life when hardcore debugging, as in my current project it can make
me waste hours at a time when something if completely fringe happens.

~~~
jeswin
I have some medium/large projects using async-await.

There are 2 ways to transpile async-await.

a) Default, with regenerator, transpiles it to ES5

b) If your env supports generators (like Node, or newer browsers), you can use
async-to-generator plugin.

Regenerator gives you unreadable code, but it will run everywhere. async-to-
generator gives you (relatively) readable code.

Source maps support has improved a lot, and you can choose to see only your
original code while debugging. You'd be setting breakpoints on your code
instead of transpiled code. So you should be fine whether you're using
regenerator or async-to-generator. There _might be_ corner cases (very rare)
depending on your env; in which case if you're using regenerator you might
need to switch to async-to-generator to find the bug.

Source maps work well with node-inspector. If you'd like to see better stack
traces in say "mocha" tests (or other test framework), use
[https://github.com/evanw/node-source-map-
support](https://github.com/evanw/node-source-map-support).

Overall, the developer experience is now pretty good. Thanks to all the work
that's gone into the tooling.

------
serguzest
It has been in Microsoft Edge/Chakra for a while. But I couldn't make it work
with Babel + webpack2. I still needed babel for static properties and React.
It was either webpack parsing couldn't recognize async/await or webpack
executes modules on Nodejs which wasn't supporting asyn/await by the time. So
bundling was failing.

I wonder if there is any babel/webpack gurus out there can make it work ?

Oh btw, I recommend windows users to try microsoft edge for debugging and
runtime inspection, it is so slick :)

------
rattray
> [esnext] prototype runtime implementation for async functions

Well, it claims to be a prototype. Can anyone from the team comment?

Quite exciting in any case!

------
z3t4
Promises are like cancer, and async/await is just treating the symptoms.

    
    
      // Callback
      dataCollection.find('somethingSpecific', function getIds(dataArray) {
        var ids = dataArray.map(item => item.id));
        display(ids)
      });
    
    
      // Promise
      var dataArray = dataCollection.find('somethingSpecific');
      var ids = pmap(dataArray, function(item) { // Cancer cell 
        return item.id;
      });
      pdisplay(ids); // Cancer cell 
      // The cancer grows ...
      function pmap (dataPromise, fn) {
        return dataPromise.then(
        function(data) {
          return map(data, fn);
        });
      }
      // The cancer grows ...
      function pdisplay(dataPromise) {
        dataPromise.then(function(data) {
          display(data);
        },function(err) {
          display(err);
        });
      }

------
lath
In the meantime there's the co library which provides the next best thing
using yield.

~~~
131hn
And a swifter way to handle legacy callback (using thunks). Co is _great_ and
work today (even in browser)

------
johnhenry
I'm definitely rooting for the feature to be included in the spec as soon as
possible, but I'm a little weary when features are added to the engine before
being standardized. Object.observe, anyone?

~~~
sodatea
The only reason that async/await hasn't been included in standard is because
there were not enough implementations.

------
chukye
Man, I used to love the times when try/catch was used to exception only, and
with exceptions that leaves the program in a bad state, I used to think when
you see a throw something really bad is going on, not just a simple ajax fail.

Dont know why people love so much async/await. In the end of the day, this all
(in node land, for instance) will be just a function call in the libuv, this
will never change, this is because the pattern is really good.. Why
overcomplicate that?

------
dclowd9901
I think my problem with this approach is the way it throws away the functional
programming paradigm JS has been sharpening over these last few years. When I
see await, I'm reminded of Java or .net, languages that didn't traditionally
have functions as first class citizens.

OTOH, I can't complain about removing dependencies like "when" or "bluebird",
and it'll be nice to not have to simulate promise returns in testing.

~~~
dvlsg
I think it's nice to have both options. I prefer the functional style of
chaining promises for the most part, but there are definitely a few times when
await is easier to use IMO (awaiting inside of a loop, for example).

------
jdgiese
Super excited to start seeing async/await in some of the browsers. Async/await
makes certain function decorator patterns even more useful, e.g.
[http://innolitics.com/10x/javascript-decorators-for-
promise-...](http://innolitics.com/10x/javascript-decorators-for-promise-
returning-functions/)

------
dkuznetsov
I like how it rhymes.

------
xanderjanz
From all my research, I feel like Promises end up making better code than
async await. Am I the only one who thinks that?

Like, what's the equivalent of Promise.all with async/await? And how do tou do
stuff synchronously after kicking off an async process?

~~~
skrebbel
I'm not sure you fully grok async/await then. Thing is, using async/await
_means_ using promises. You can't use async/await without promises. An async
function returns a promise. _Always_. (in a way, `async` can be seen as
something of a type annotation).

If you want to use async/await with something that's asynchronous but not
Promise based, you'll first need to convert it into a promise before you can
async/await it. This is actually very elegant in my opinion: instead of
proposing _yet another_ way to do asynchronicity in JS, async/await fully
embraces Promises, which you already know.

Of course, this means that async/await also has all of Promise's downsides.
For example, you can only resolve a promise once, so neither Promises now
async/await make dealing with streams of asynchonous events any easier.

~~~
jdc0589
I don't see that as a downside. Callbacks make sense for the pipelining
portion of async streams. I usually wrap things up such that i set up my
callback/event based stream pipeline, and then have a promise that gets
resolves on completion/end. That way your stream code is 100% normal
callbacks, and you still have promises/async/await for overall flow control.

------
treenyc
What about this nodejs async,

[https://github.com/caolan/async](https://github.com/caolan/async)

May be a replacement until the async is implemented in V8

~~~
onestone
It's not a replacement at all, and has almost nothing in common with what is
discussed here (except the name).

------
avodonosov
what's the point of explicitly declaring functions "async", and then
explicitly saying "await". IMHO all this could be done automatically by
language.

~~~
jeswin
Because you don't always have to await a function, and it isn't always
possible for the runtime or language to decide whether to "await" or not.

    
    
      /*
        The following code may or may not use an await.
        Not await-ing would be better user experience.
      */
    
      async function sendEmails(id) { ... }
      
      async function signUp(userData) {
        const user = await db.saveUser(userData);
        sendEmails(user.id); // <-- Not awaiting send to complete
        return "Congrats. Signup complete!"
      }
    
    
      /*
        On the other hand this code needs an await:
      */
    
      async function updateGlobalState(obj) { ... }
    
      async function doSomething(data) {
        await updateGlobalState(data); //await needed
        return global.x;
      }

~~~
grandalf
is the non-awaiting one guaranteed to finish (assuming no errors)?

~~~
spb
It's guaranteed to return as soon as the thread of execution finishes prior
immediately-pending callbacks (since it's basically a synchronous function
call with an awaited return value). It's "finished" as soon as it's finished
_initiating_ the send, since it doesn't await the result.

(The _exact_ point where this gets resolved, relative to other pending
callbacks/resolutions, is a very wonky detail involving constructs not exposed
at the language level, which varies from engine to engine in spite of what the
standard says: [https://jakearchibald.com/2015/tasks-microtasks-queues-
and-s...](https://jakearchibald.com/2015/tasks-microtasks-queues-and-
schedules/))

Whenever the call resolves, even if the send _does_ encounter errors, this
function or its caller aren't going to know about it either way. That's why
this kind of promise-abandonment is pretty bad design - I wouldn't be
surprised if there's already a draft in the works for some kind of "use
strict" option that causes warnings / crashes when synchronous code finishes
with Promises unreferenced (or at least something in tooling / profiling to
trace 'promise leaks').

~~~
grandalf
Interesting!

------
z3t4
I can't see how wrapping everything in a promise and a try/catch, plus adding
async/await is any easier then a callback.

~~~
msoad
Exactly! When you count for nested try/catchs you see no significant
improvement

~~~
WorldMaker
Why would you nest try/catches? At worst you get try/catch parades:

    
    
        try {
          await thing1()
        } catch (e) {
          console.log(e)
        }
        try {
          await thing2()
        } catch (e) {
          console.log(e)
        }
        // ... and so forth ...
    

That's still nothing like the pyramids you get in callback world.

~~~
msoad
That won't work because if thing1() throws you usually don't want to process
to thing2

Take this for example:

    
    
         const response = await fetch('./api.json');
            try {
                const json = await response.json();
                console.log('YAY! JSON!', json);
            } catch (jsonParseError) {
                alert('damn it!');
            }
         } catch(fetchError) {
            console.warn('this is not cool');
         }

~~~
WorldMaker
Okay, that's a fair counter-argument. My gut feeling is that's possibly one
catch to many and as much as possible I'd want to try to merge the two
catches/unifying the error response logic.

Another idea is that you could reformat to a "parade" try/catch by adding
returns to the catch:

    
    
        try {
            const response = await fetch('./api.json')
        } catch (fetchError) {
            console.warn('this is not cool')
            return // Exit
        }
        try {
            const json = await response.json();
            console.log('YAY! JSON!', json);
        } catch (jsonParseError) {
            alert('damn it!');
        }
    

Obviously you'd need to move any code you'd want to run regardless of error up
into the parent function or out into a wrapper function.

------
jcoffland
The one extra diff I would really like to see in that list is some
documentation. The V8 docs have always been too sparse.

------
ConAntonakos
So what does this mean in terms of being implemented in Node.js? How soon can
we expect that to happen?

------
derrickroccka
This is so good. Great days for JS. This is going to save us from a lot of
headaches.

------
ihsw
Realistically does this mean we will see async/await in node-v7.0?

~~~
AgentME
I hope the node APIs are changed/extended to return promises eventually so I
don't have to keep on using promise wrappers for all of them.

~~~
BinaryIdiot
Is there a reason you always wrap them? Even if it's awkward I tend to leave
most platform APIs alone and treat them as special cases if I'm doing
something, say, promises or messages.

~~~
WorldMaker
Promises are much each to compose. Promise objects can be passed around and
reused. (Multiple things can wait on the result of the same promise.) Code is
much easier to read with flat .then() and .catch() chains, versus sometimes
the "pyramid of doom" callbacks can create. Code is much, much easier to read
with Promises when you can use async/await, and getting everything wrapped to
promises now makes it that much sooner you can use async/await.

~~~
BinaryIdiot
I get the why people want to use Promises in general but when they're used to
simply wrap a standard node / browser call feels dirty to me because it
changes what you expect it to return (e.g. a promise instead of whatever it
normal returns).

I dunno I just don't like to give the impression I'm changing anything about
how I'm accessing / using the standard library but I guess this is a bit
subjective.

> versus sometimes the "pyramid of doom" callbacks can create

If you structure the code well you never run into this (callback soup is very
overblown; if you find yourself in that position then someone screwed
something up). But I get promises and async / await are nice :)

