MatAtBread / fast-async

603 stars 21 forks source link

What babel options to get the promise transformation ? #1

Closed rom1504 closed 8 years ago

rom1504 commented 8 years ago

I'm trying this:

var options = {
    presets: ['es2015','stage-0'],
   plugins: [["fast-async",{compiler:{promises:true}}]]
};

but it somehow doesn't output promises

Edit: Ah I guess I do need to exclude the transform-async-to-generator plugin

Edit2: ok I got it to work by excluding transform-async-to-generator (manually specifying the plugins I need from stage-0)

It seems nodent/fast-async doesn't handle async methods though ?

class A
{
async f()
{
return 5;
}
}

Edit3: well in the end that unhandled method bug was my real problem, letting stage-0 in presets is okay

matAtWork commented 8 years ago

So....you got it to work, right?

FYI, for various reasons (I'm not a babel power-user), the plugin defaults to using Promises (see https://github.com/MatAtBread/fast-async/blob/master/plugin.js#L43), and I've not updated it to use ES5 or generators. I'm in the process of preparing a release for nodent, and I'll try and squeeze this in when I update the dependents.

rom1504 commented 8 years ago

Yes I got it to generate stuff, but it seems the behavior is a bit different from the generator implementation of async/await of babel and that I'm getting a bug because of that (https://github.com/roblabla/ProtoDef/pull/40).

I don't know what this is about more precisely, it might just be something I do slightly wrong in my code. I'm still experimenting, trying to get decent perf with various possibilities (bluebird promises, fast-async, bluebird coroutine,...) The winner is currently just manually writing bluebird promises.

matAtWork commented 8 years ago

Hmmm....TBH, the behaviour should be pretty identical to the default generator implementation, and very close to writing Promises (that's what it does basically). Can you try pasting you code into nodent.mailed.me.uk and send me the link? If there's a bug, I'd like to track it down.

I've noticed that the Babel guys have (yet again!) modified the ESTree spec they're using in the latest release, which might have broken something - specifically the Node type "Property" seems to have disappeared, so I'll need to update the plugin to match what they've done.

matAtWork commented 8 years ago

Just found the reference (https://github.com/babel/babel/commit/7955548ad1d9b56b48e7279aa54dd346bb09a07d) - I'll have a go at making it work tomorrow. The move from babel5 to 6 changed quite a lot of things.

rom1504 commented 8 years ago

@matAtWork it seems there is indeed a bug

Here is a minimal case

and even this

There is no call to $return in the compiled code.

Or maybe this is actually a babel bug that made my code work by accident ? Aren't async function allowed to not return anything ?

MatAtBread commented 8 years ago

Take a look at https://github.com/MatAtBread/nodent/blob/master/README.md#implicit-return

To cut a long story short, you need a return value.

I had a look at the updated Babel spec, and it needs fixing at my end. It will (probably) show itself as an inability to use async as object methods and properties, but should be easy to fix

MatAtBread commented 8 years ago

... Although the return can be undefined, as in return;

rom1504 commented 8 years ago

Are you quite sure the spec says that ? I found lot of examples on the web that don't have a return in all cases. And babel do accept that (hence the difference of behavior)

matAtWork commented 8 years ago

Omitted 'return' is perfectly legal. It's a documented artifact of nodent's implementation (see https://github.com/MatAtBread/nodent#gotchas-and-es7-compatibility). The workaround is very simple - always have a return or throw in your code, this ensures compatibility with both nodent and the spec.

The reason for this is to allow for the 'async return/throw' extension (not supported by babel), since you need a way to not return from an async function immediately but defer the return until later. In general, I'm not in favour of extensions or deviations from specifications, but this one is very useful in interfacing with legacy code - nodent has been in production systems for over two years and the performance gains of using callbacks as opposed to generators is vital for us (our site does over 50m events a day), and the workaround is trivial (although I totally accept that unless you dig into the documentation it'd leave you confused!).

The babel plugin is kind of an afterthought - some people on our team use babel, but in general we don't - nodent and ES5-6 form the backbone of our code.

matAtWork commented 8 years ago

Hey - this should now all be fixed in v6.0.6 and nodent v2.3.0. I'd missed some changes the AST format used by Babel 6, and functions that run to completion now return 'undefined' asynchronously (the previous behaviour is only useful for the 'async return/throw' syntax, which Babel does not permit).

I appreciate your feedback - I prompted me to think through a number of issues and the 2.3.0 release is better as a result.

I'll close the issue - obviously if you still have problems feel free to reopen/comment.