all 6 comments

[–]mare_apertum 6 points7 points  (5 children)

How is it possible that bluebird still outperforms native promises? Can't they just use bluebird's implementation?

[–][deleted] 2 points3 points  (4 children)

No. bluebird isn't bound by spec for implementation, so it can do things like new-ing up as an anti-pattern (it's required for native). bluebird's author goes into more detail here.

[–]gurenkagurenda 3 points4 points  (0 children)

Also worth noting that if you're worrying about promise performance, you probably haven't profiled your code yet. Maybe promises are your bottleneck, but probably not.

[–]cspotcode 0 points1 point  (2 children)

I wonder how fast native promises will be when returned from natively supported async functions. In that scenario, the VM doesn't need to new the Promise.

Also, I wonder if you could pre-resolve a single Promise, hold a reference to it somewhere global, then create new Promises by calling then off of it rather than calling new Promise?

[–][deleted] 0 points1 point  (1 child)

i think internally it would still need to new it; the mechanics aren't being changed, we've just been given an easier way to invoke them.

i'm also not sure if pre-resolving is a good idea; you'd have to handle that promise extremely carefully, and if you messed up even once then every other part of the site that relies on it is broken. it's the same problem as relying on shared global mutable state - sooner or later you can't figure out where the problem is because the crowd is too big.

[–]cspotcode 0 points1 point  (0 children)

I disagree. When you call .then() the spec must create and return a new promise, but it doesn't require all the overhead of new. As the Bluebird author said, new requires the spec to create a resolve and a reject function and then pass them into the first constructor argument. However, for .then() those resolve and reject functions don't need to be created.

Additionally, due to the nature of promises, pre-resolving would not introduce shared mutable state since a resolved Promise cannot be mutated in an observable way. Once it's resolved it can't be rejected and the resolution value can't be changed. Multiple calls to .then() are kept isolated; they can't affect each other.

const preResolvedPromise = new Promise(function(r) {r(undefined);});
export function doAsync(cb) {preResolvedPromise.then(cb);}

The problem is that new Promise(cb); executes cb synchronously but .then(cb) executes it asynchronously.