23 comments

[ 2.8 ms ] story [ 60.5 ms ] thread
If your target environment has promises and generators available, I'm fond of using Babel's first-party `transform-async-to-generator` plugin, which barely alters your code's syntax: https://babeljs.io/docs/plugins/transform-async-to-generator...
Author of Kneden here. If generators are avaiable, you should probably indeed be using this.

If they are not though, Kneden will generate code that's probably more readable and smaller (no polyfill except for a Promise implementation).

Is Babel's generator transpiling support good enough to allow this to be transpiled down to ES5?
If your looking for es5 promises are much easier to polyfill and much more competitive than generators
Can you clarify what you mean by 'competitive'? Are you talking about performance, or some other measure of quality?
It is, the resulting code is just a bit harder to read, and the babel-polyfill is required. It's quite good considering they're transpiling generators actually, but it's hard to beat something working on a higher level (async/await straight to promises, like Kneden does.)
It's actually how babel's "standard" async/await support works. First to generators, then generators to ES5-compatible code using Facebook's Regenerator (which includes a polyfill).

Pragmatic and it works, but the code isn't pretty. Which is why Kneden was made.

Have you run any sorts of performance benchmarks on this?

I like async/await a lot, but I'm concerned at how much all of this JS machinery costs in terms of perf, especially compared to writing callback chains.

I haven't. It probably mostly depends on the JS engine and Promise implementation.

That said, it might be a good idea to hand-optimize that single hot loop, typing the Promise chain out yourself, or even using callbacks directly. It's impossible to beat that using an automated solution like this.

This is why the JS ecosystem frustrates me. We're talking about an ES7 -> ES6 transpilation, which I will then have to transpile again to ES5. And that's before we even hit the VM/JIT.
(comment deleted)
Don't forget to sprinkle in JSX and TypeScript, so that transpilers have to support the cross product [ES5, ES6, ES7] X [JS, JSX] X [JS, TypeScript].
Meh, the ES6 features this needs don't need transpilation, just Promises. They're perfectly well stubbable with a library (such as Core-js or Bluebird) so you don't actually need to transpile stuff "again" to ES5.

But note that it's shipped as a babel plugin, so you shouldn't even need to care.

What this really is is "use the currently-most-popular JS transformation toolchain to transform cool-JS to works-in-browser-JS". Whether part X is in the ES6 standard and part Y might end up in ES7 is really mostly besides the point.

Or you can stick to ES5 like I do, and just use typescript definitions to help you with code validation and type checking. The problem is frameworks pushing a lot of non standard features, like Angular does, on the premise that it might be part of the spec one day. That's a dangerous bet.
The beauty and goal of Babel and it's plugins is you can use future JavaScript today, and when that future JavaScript is now considered today's JavaScript, you can remove Babel and your code just works.

This isn't like TypeScript or CoffeeScript where you're always transpiling.

Or don't use undeveloped language features until they're available. I'm very happy with the subset of ES6 available on node, but I never shared the complaints many people have of "callback hell". It's really not difficult to deal with and adding promises doesn't magically make it better, I've seen my share of promise hell.
Yes, except that the asynchronous hells finally go away when you start using async/await. Makes code easy to read, write, and reason about.
Or just don't use this. Wait until these language features are natively supported. It's your choice. There's no need to be frustrated by something that you don't use.
I really hope it won't happen and we've learned from the past, but is it possible we'll soon be transpiling for different browsers and using conditional comments for loading the right version?
The last time I tried async/await with Babel I had huge problem that my code was very hard to debug. When runtime error occurred it did not show any useful information, like error line number, and thanks to transforming and regenarator-runtime wrapping of my code, it was nearly impossible to step through the code in any meaningful way, so I had to fallback to console log driven development.

Maybe something changed since the last time I tried, or perhaps i mis-configured something? How are error messages and debugging with this plugin?

The end result is more comprehendable than the regenerator output, but the code is still modified quite a bit to fit into a Promise chain structure. Some statement types (like loops) more than others (like a simple function call). I haven't paid special attention to source maps and the like yet apart from what Babel itself generates (which is quite a bit), so there's probably still quite a bit to gain here.