
Microsoft Edge gets native ECMAScript 7 async/await support in latest build - JoshGlazebrook
http://blogs.msdn.com/b/eternalcoding/archive/2015/09/30/javascript-goes-to-asynchronous-city.aspx
======
daveidol
The first time I heard of async/await was actually with Microsoft C#; so I'm
not too surprised to see them prioritize this feature in JS land.

...which is cool, because using async/await in C# made me realize how much
simpler dealing with async code could be (compared to my experience with JS
callbacks or Java threads).

~~~
PopsiclePete
I'm a little sad the async/await model is winning over. I really prefer Go's
CSP. It can do everything the async/await model can, plus "streaming" API's. I
dig (sorta) C#'s async/await, but I still don't see why it's "winning" over
other, better models...

~~~
bklimt
The one advantage of C#'s async/await over Go's CSP is that by exposing the
underlying Tasks, you can take more control over how the continuations get
executed. The result of this is that it's easy to have async code that all
runs on the same thread (usually the UI thread) even while it calls a function
makes a network request that gets scheduled to a background thread.

Go's model doesn't give you as much control over which thread a particular
operation gets assigned to. It's not theoretically impossible, I suppose, but
it's hard to imagine what a simple API for it would look like.

But yes, if this particular problem were solved in an elegant way, I would
also prefer the CSP model. It makes it so you don't have to worry about which
operations are async or not.

~~~
novaleaf
A huge problem with C#'s Async feature that I hope gets resolved (and,
obviously that this failure pattern is not ported to Javascript): Explicitly
blocking during a function that uses async somewhere inside (a sub-function)
will cause your application to deadlock. It is extremely surprising that .NET
does not handle this (abet novice) design mistake in a graceful way. (For
example, checking if a thread is blocked before attempting to schedule tasks
to it)

------
nailer
For anyone unfamiliar with JS, async/await is about the best JavaScript will
ever get:

    
    
        var orders = await getJSON('/users/joe/orders');
    

No callbacks, promises etc (Edit: that you have to look at, as other posters
note the implementation uses promises in the background).

You still have to explicitly say you want to be async, so it's not quite as
good as non-blocking IO in something like Elixir, but it's the future as far
as JS goes.

~~~
jlongster
_There are promises there_ , it just hides it. All async functions return a
promise, and `await` works with promises builtin. It's basically the same
thing as generators, without the `function*` syntax.

Which is unfortunate because async/await only works with promises, and if you
want any other async model (like one that doesn't eat errors all the time) you
can't use it. Luckily, generators are fine.

~~~
nvivo
What do you mean by "if you want any other async model you can't use it"? I
know you can write whatever code you want, but promises are supposed to be the
_standard_ way of signaling completion of asynchronous operations in
javascript.

This is the same as saying that "arrow functions only works if you want to
represent functions".

Also, promises don't eat errors. It's the code using those promises that
_forget_ to handle them.

The async/await fixes that by unwrapping those errors for you. Any errors in
an "await expression" will be thrown as exceptions up the stack.

~~~
jlongster
> What do you mean by "if you want any other async model you can't use it"?

Promises are not the only way to do async work in JS, as much as some people
like to say that. You have observables and channels, which are more powerful
because they handle streaming.

There are proposals to make async/await more composable:
[https://github.com/jhusain/compositional-
functions](https://github.com/jhusain/compositional-functions). TC39 is aware
of this but I'm not sure if they are going to fix it or not.

> Also, promises don't eat errors. It's the code using those promises that
> forget to handle them.

They literally do. They run your code in a try/catch block and store the error
away, and you have to remember yourself to manually throw it later. You
shouldn't be forced to run code inside a try/catch.
[http://jlongster.com/Stop-Trying-to-Catch-Me](http://jlongster.com/Stop-
Trying-to-Catch-Me)

~~~
coldtea
> _I don 't care about awkward .then() syntax. I don't mind automatic error
> propagation. I don't care having to call .done() on a promise chain. I don't
> care about losing the stack (which is inherent in any async work). I care
> that promises grab all errors, just like try/catch._

You should stop caring about that and start caring about the other stuff.

"Breakpoint on exception" still works, albeit slightly altered, and in any way
it's a minor detail compared to the far better mental model for code execution
that async and promises bring.

> _I want to make stupid typo errors and have them appear as normal errors,
> not caught by promises._

For stupid typo errors use a linter and/or a transpiler like babel in the
first place.

> _It 's cool, I just don't understand why everyone is so excited about a
> simple syntactic improvement._

Because better syntax brings code closer to how we think, and reduces errors.

------
tlrobinson
For those wanting to use async/await _everywhere_ , _right now_ , it can be
transpiled using Babel or similar (in Babel you need to enable the
"es7.asyncFunctions" feature:
[https://babeljs.io/docs/advanced/transformers/#es7-experimen...](https://babeljs.io/docs/advanced/transformers/#es7-experimental-)
)

~~~
AgentME
Current versions of Babel default to having es7.asyncFunctions enabled.

~~~
ilaksh
Serms like I still need --optional runtime and babel-runtime though, right?

~~~
AgentME
You need to do that, or include the global polyfill:
[https://babeljs.io/docs/usage/polyfill/](https://babeljs.io/docs/usage/polyfill/).

If you're writing a library, use the runtime option. If you're writing a
website or other standalone app, you should use the polyfill (especially if
you use other libraries like React which depend on ES6 globals too).

------
Sephr
Firefox has had this for over 6 years through my async.js[1] library that
relied in JavaScript 1.7's pythonic iterators and generators. The syntax is
similar, as you have to mark/encapsulate functions with async() to use the
library.

1\. [https://github.com/eligrey/async.js](https://github.com/eligrey/async.js)

~~~
colordrops
You may want to consider renaming your library. There's already a very popular
lib with the same name:
[https://github.com/caolan/async](https://github.com/caolan/async)

Edit: it appears that the caolan async lib came out after yours. Sorry for the
confusion.

~~~
Sephr
Don't you mean the other way around? Mine was out years before theirs. They
should have googled the words "async.js" (which my lib was the top result for
prior to caolan's repo) before naming their project.

~~~
LewisJEllis
Years? Really? Not to nit, but the only way "years" is accurate here is if you
mean "0.3 years".

Your first commit was that January and Caolan's was that May, and when yours
was "out" is debatable anyway since you don't have any releases tagged.

I would hardly feel obligated to rename a project over a 4-month-old Github
repository that doesn't even target the same platform (Firefox vs. async being
originally Node-only).

------
chenglou
I guess I'll take this occasion to post this:
[http://journal.stuffwithstuff.com/2015/02/01/what-color-
is-y...](http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-
function/)

Which argues that async/await might not be what we really want in the end. As
a user of Promises and async/await in the future, it's a very interesting
read!

~~~
skybrian
It's a great blog post, but be careful what you wish for. If you have true
preemptive threading as in Java or Go, a race condition can happen anywhere. I
suspect many JavaScript developers would be sad about not having atomic event
handling by default and having to learn to code much more carefully.

Even in Java UI frameworks like on Android or Swing, you have an event loop
with a single thread, and when spawning another thread you have to deal with
special communication layers [1]. True multithreaded UI's seem like an area
for research.

[1] [https://developer.android.com/training/multiple-
threads/comm...](https://developer.android.com/training/multiple-
threads/communicate-ui.html)

~~~
HeyImAlex
Yeah, the event loop can be a constraint but it's easier to think about and
harder to mess up compared threads or channels. And really how much are you
giving up? Most of the things you actually want to wait on have an async api.
Maybe I just haven't built complex enough things, but I've never had to reach
for web workers because of performance concerns.

------
jongleberry
We're moving Koa to be ready for async functions. Does anyone know whether
async functions will have an arrow function form?

[https://github.com/koajs/compose/pull/27#issuecomment-144868...](https://github.com/koajs/compose/pull/27#issuecomment-144868219)

~~~
hekul
Yes - async functions do have an arrow form:
[http://tc39.github.io/ecmascript-asyncawait/#prod-
AsyncArrow...](http://tc39.github.io/ecmascript-asyncawait/#prod-
AsyncArrowFunction).

------
callahad
If you'd like to follow along on the Firefox side, CC yourself on
[https://bugzil.la/1185106](https://bugzil.la/1185106)

------
swang
I feel like Microsoft doing this is their new attempt at trying to dominate
how the web will be shaped. I know the likelihood of async/await being bundled
with ES7/ES2016 is pretty high but lets say it gets delayed for further
review, is Microsoft going to wait until these specs are "official" before
releasing it into standard non-preview Edge or are they just going to rush it
as fast as possible, pat themselves on the back and then shrug their shoulders
when their syntax is completely different from the actual ES7 implementation?

async/await is important and highly desired by the community, but I would
prefer if it were not Microsoft trying to blast ahead and create yet another
separate fragmentation between browsers. Sure they call it an experimental
feature, but how long until they decide, "well we're not going to wait for
this to get finalized, we're releasing it for everyone!!!" ?

------
mschuster91
Finally, a way out of callback hell. Now, make this work with IndexedDB and I
might revisit IDB.

~~~
streptomycin
Here's some work towards that: [https://github.com/inexorabletash/indexeddb-
promises](https://github.com/inexorabletash/indexeddb-promises)

Still a ways to go, though...

------
msoad
I'm surprised to see Microsoft put a higher priority for async/await than
finalized ES2015 spec. Some of ES6 stuff are still missing in Edge.

As a side note, I don't like how async/await has to be wrapped in try/catch
AND a function for proper error handling

    
    
        (async ()=>
          try {
            let result = await fetch('/file.json');
            let json = await result.json();
            console.log(json):
          } catch(error) {
            console.error('Not sure fetch failed or toJson');
          }
        )();

if you want to handle each error separately you need even more try catch!

~~~
nvivo
To be fair, all browsers are still missing ES6 features and all of them have
newer stuff being implemented.

As for the try catch, you don't NEED to wrap. The sample just shows you can.
You can't do:

    
    
      try {
          promise.then(() => ...);
      } catch {}
    

but you can do

    
    
      try {
          await promise;
          ...
      } catch {}
    

async/await is a way to write simpler code the same way you would use a "for"
block instead of a "while(iterator.next())" \- because it's easier, all the
rest is still the same.

~~~
msoad
You need to wrap in try/catch if you want to handle the errors, which is the
same for sync functions that throw to be fair. But most of async operations
are somehow expected to fail due to their nature (like network calls) and
people usually want to have error handling scenarios. But for sync functions
we usually let the error terminate the program because if a sync function
throws in runtime it means something is wrong in my program, not in
networking...

~~~
nvivo
> You need to wrap in try/catch if you want to handle the errors.

Of course, the same way you need to add a second callback to a promise handler
if you want to handle errors. There is no difference, really. You're just
changing the way you write the code.

Also, you're not forced to choose "await or promises". You can use both as you
see fit, in the same block:

    
    
       async () => { 
          // make 2 requests in parallel
          var p1 = fetchSomething();
          var p2 = fetchAnotherThing();
    
          // wait for both of them to be done
          await Promise.all(p1, p2);
    
          // continue when they're both resolved      
          // these "await" only get the values since the promises are resolved
          doSomethingWithTheValues(await p1, await p2);
       }
    

> But for sync functions we usually let the error terminate the program
> because if a sync function throws in runtime it means something is wrong in
> my program, not in networking

This is just the way you're choosing to see the problem. Promises can be used
for anything, it's not tied to networking. I usually write promises that will
be resolved when a modal window closes or when an application event happens.

It's just a simpler way to write code. The way you use it is up to you.

Also, async/await makes debugging a lot easier. The debugger can understand
that the next expression after an "await" is supposed to be in the same
function context. No more adding breakpoints to the callback function because
only you know how the code is called at runtime. You debug async functions as
normal functions.

------
grayrest
I wish the we were getting F#'s computation expressions+asynchronous workflows
(monad sugar) instead of C#'s async/await.

~~~
louthy
You could try funscript[1]:

"F# to JavaScript with type providers

FunScript is a lightweight F# library that lets you rapidly develop single-
page applications. You can connect to external data sources and call REST APIs
with intellisense, produce dashboards using JavaScript visualization libraries
and write asynchronous computations easily without explicit callbacks."

[1] [http://funscript.info/](http://funscript.info/)

------
dcherman
I'd be curious about one potential downside to this (v8 specific, maybe others
too)

Functions that contain a try/catch cannot currently be optimized by V8. If we
migrate to using try/catch rather than `.then/.catch`, I wonder if there's
going to be any perf implications since previously optimizable functions may
no longer be optimized.

------
z3t4
"await" will not help you if you do not understand the asynchronous nature. I
think it's a unnecessary abstraction. And it's much easier to follow callbacks
if you abstract them like this:

    
    
      socket.on("data", echo); // calls the echo function when data arrives

------
tkubacki
I'm heavy Dart with dart2js user. Dart has await/async from few releases

It is really a relief when it comes to multiple AJAX/UI dependant logic eg.

if(await showDialog("get coffe ?") == "yes"){

    
    
      results = await getCoffeFromServer();

} else { ... }

------
dang
Also
[https://news.ycombinator.com/item?id=10310932](https://news.ycombinator.com/item?id=10310932).

------
moo360
Now if they would implement the HTML5 file drag & drop api like _literally
every other modern browser_ then may be people would actually use Edge.

~~~
Loque
O the tone of MS harping on about what Edge is doing feels like smoke and
mirrors to me whilst IE11 will remain one of our lowest common denominators
for some time. I respect that a team would love to forget about IE11, but MS
is the only company that has any control over it... so whilst they dazzle
people with c# style syntactical sugar and pushing typescript (which we will
have to compile down to ES5 anyway) I find it hard to get excited about Edge.

Get the basics done right first imvho. I don't want developers staying late to
try and understand why something isn't working in a MS browser anymore.

------
josteink
But it's still "just IE", right? Right guys?

Seriously though. I think that argument is losing steam every time I do
testing with Edge. It gets updated. It _feels_ different.

Unless somebody were to tell me both IE and Edge belong to the same browser
family, I wouldn't be and to tell.

I'd say it's fair to call it a new browser.

~~~
camhenlin
Canvas performance still pretty awful compared to more modern browsers.
Source: [http://www.networkworld.com/article/2979845/microsoft-
subnet...](http://www.networkworld.com/article/2979845/microsoft-
subnet/microsoft-edge-browser-performance-test-chrome-firefox-internet-
explorer.html)

~~~
nvivo
Just being picky, but because Edge was released after all other browsers,
technically there isn't any other "more modern browser". There are just the
other browsers.

------
nowprovision
Do we have an ES7 compiler to ES6 that can handle these new features? Whilst I
prefer cljs, sometimes the weight of clojurescript output and tooling can be a
little offputting for smaller tasks, but callbacks/promises etc.. are rarely
enjoyed

~~~
indeyets
[https://babeljs.io/](https://babeljs.io/)

------
mkozlows
Leaving the Edge news aside, that article starts off by defining event
listeners as callbacks, which is awfully weird.

