Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrate Q to BlueBird (or Vow)

I'm current using the Q promise library in a Node/amqp app. I've read that the performance of Q vs libraries like BlueBird or Vow is... not so good.

Unfortunately, I can't figure out how to use BlueBird (or Vow) to replace my current Q usage patterns.

Here's an example:

this.Start = Q(ampq.connect(url, { heartbeat: heartbeat }))
    .then((connection) => {
        this.Connection = connection;
        return Q(connection.createConfirmChannel());
    })
    .then((channel) => {
        this.ConfirmChannel = channel;
        channel.on('error', this.handleChannelError);
        return true;
    });

I should've mentioned - I'm using TypeScript... In this example I'm taking an amqplib promises, and creating a Q promise out of it (because I don't like the amqplib promises). How do I do that with BlueBird or Vow?

Another example is:

public myMethod(): Q.Promise<boolean> {
    var ackDeferred = Q.defer<boolean>();

    var handleChannelConfirm = (err, ok): void => {
        if (err !== null) {
            //message nacked!
            ackDeferred.resolve(false);
        }
        else {
            //message acked
            ackDeferred.resolve(true);
        }
    }

     ...some other code here which invokes callback above...

    return ackDeferred.promise;
}

How is that pattern implemented?

So my general questions is:

  1. Are the performance differences I've read about true?
  2. How do I migrate from Q to BlueBird or Vow, with a focus on those two patterns (but an explanation of using 'then' would be great, too)?
like image 884
Michael Avatar asked May 19 '14 17:05

Michael


1 Answers

Yes, Bluebird is two orders of magnitude faster than Q, and is much more debuggable. You can look at the benchmarks yourself.

As for the code:

  • Q() maps to Promise.resolve in Bluebird (just like in ES6 native promises).*
  • Q.defer maps to Promise.defer() although it's a better option to use the promise constructor or automatic promisification as explained in this answer. In short, the promise constructor is throw safe.

Note* - once you've cast the promise, it'll assimilate thenables from other libraries automatically - so this is perfectly fine:

this.Start = Promise.resolve(ampq.connect(url, { heartbeat: heartbeat }))
.then((connection) => {
    this.Connection = connection;
    return connection.createConfirmChannel());
})
.then((channel) => {
    this.ConfirmChannel = channel;
    channel.on('error', this.handleChannelError);
    return true;
});
like image 125
Benjamin Gruenbaum Avatar answered Sep 17 '22 14:09

Benjamin Gruenbaum