Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Official recommendation for using Bluebird with async functions? #1434

Closed
wearhere opened this issue Aug 7, 2017 · 5 comments
Closed

Official recommendation for using Bluebird with async functions? #1434

wearhere opened this issue Aug 7, 2017 · 5 comments

Comments

@wearhere
Copy link

wearhere commented Aug 7, 2017

Hello folks. First off I recognize that (despite your support guidelines) I am asking a support question, that has already received an answer on Stack Overflow. But a disadvantage of that channel is that I can't tell if that's an "official" recommendation or just some random user trying to be helpful.

I also feel like this discussion should be documented somewhere on bluebirdjs.com, whereas currently async functions don't get any mention there. (Closest is a mention of C#'s async functionality on Promise.coroutine. But what about in JS? async/await have been natively supported for multiple versions of V8 now.)

So—do the Bluebird maintainers have any position on the best way to use Bluebird with async functions, with an eye to functionality and/or performance? Suggestions:

  • somehow cause async functions to return instances of Bluebird promises rather than native promises? (Noting that changing global.Promise is not sufficient as shown here and here. It sounds like this guy may have found a way to do this but he doesn't show his code unfortunately. I have a comment pending on that post, we'll see.)
  • wrap async functions in Bluebird.method?
  • use a Babel plugin like this to convert async methods into Bluebird's coroutine and method helpers?

Related: #1426 (comment).

@benjamingr
Copy link
Collaborator

Basically, over the years we've added to the platform all the features that made native promises awful back then (swallowing errors) and from the other side there has been a lot of effort from V8 to optimize native promises and from platforms to provide stable APIs for them.

My recommendation would be to use bluebird for collection methods and when you need performance over async functions (that might change) while you should likely use native promises for everywhere else.

The big pain points bluebird aimed to solve were addressed by native promises. Bluebird still has very useful APIs (like promisification of a whole module, cancellation or collection methods).

  • For promisification use promisifyAll to promisify a whole module and util.promisify for smaller stuff. We only recently got util.promisify and it probably will get better
  • If you need to support older environments or are building a library that might - prefer bluebird.
  • For collection methods it is very useful.
  • There are still cases where bluebird's performance is considerably better.

Other than that - prefer native promises. They are the future. There is no official way to use bluebird promises with async/await - (there was a proposal for that that was for observables but would have worked with bluebird - it got turned down). Using a babel plugin works - but if you care about performance Babel isn't great anyway.

Bluebird has 17.5 million downloads a month - I hope the native platform gets good enough to get those numbers down - and we're working on it :)

@wearhere
Copy link
Author

wearhere commented Aug 7, 2017

Thanks for the thoughtful response @benjamingr! That's great to hear that you don't consider the performance differences to be a blocker or insurmountable, it seems like your response runs a bit counter to earlier comments from Bluebird folks ("Even if V8 implemented the same optimizations as bluebird, it would still be hindered by specification.")

Using a babel plugin works - but if you care about performance Babel isn't great anyway.

Oh interesting, is async/await with native promises faster than generators i.e. Bluebird.coroutine, what the plugin transpiles into?

Btw is there anything from the above that you'd like to add to somewhere in the documentation? Glad to put up a PR if so.

@benjamingr
Copy link
Collaborator

That's great to hear that you don't consider the performance differences to be a blocker or insurmountable,

The situation when ES6 promises were introduced was that they were not really usable. Petka implemented unhandled rejection detection in Node a year and a half ago, the default was changed to warning about a year ago, and util.promisify is just a few months old.

It's better, bluebird still probably provides better developer experience in most cases but it's not clear cut.

Even if V8 implemented the same optimizations as bluebird, it would still be hindered by specification. The benchmark has to use new Promise (an anti-pattern in bluebird) as there is no other way to create a root promise in ES6

@wearhere we fixed that by adding .promisify to Node.js and exposing the host environment hooks.

This literally took changing the platform. It was a hard battle that took us years of convincing.

Oh interesting, is async/await with native promises faster than generators i.e. Bluebird.coroutine, what the plugin transpiles into?

Bluebird.coroutine is still likely faster - but note that TurboFan can do optimizations that bluebird cannot with async functions - and over time it will get better. For example it can detect you await a value that's already resolved to a value and optimize that into just replacing your code with the value.

I'm not sure about the documentation.

@wearhere
Copy link
Author

wearhere commented Aug 8, 2017

Bluebird.coroutine is still likely faster - but note that TurboFan can do optimizations that bluebird cannot with async functions - and over time it will get better.

Super cool, thanks for the information @benjamingr, and for your / the other maintainers' hard work over the years to get the platform to this point!

That's cool on the docs, just wanted to offer in return for you posting everything here. :) Closing for now then.

@wearhere wearhere closed this as completed Aug 8, 2017
@arpitjacob
Copy link

awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants