Anthony
Anthony

Reputation: 14279

Can't get a non-node callback library to work with Bluebird promisfy

I'm trying to use a library which doesn't implement the node convention of having a falsey value passed as the error value if no error is present, which is used for Bluebird's promisifyAll function.

The implementation of the API can be found here: https://github.com/sintaxi/dbox/blob/master/lib/dbox.js

I've implemented a custom function to get around this, but I can't get the second value to be printed to the console when using it.

function NoErrorPromisifier(originalMethod) {
    // return a function
    return function promisified() {
        var args = [].slice.call(arguments);
        // Needed so that the original method can be called with the correct receiver
        var self = this;
        // which returns a promise
        return new Promise(function(resolve, reject) {
            args.push(resolve, reject);
            originalMethod.apply(self, args);
        });
    };
}

var client = Promise.promisifyAll(app.client(token), {
  promisifier: NoErrorPromisifier
});

client.accountAsync().then(function(status, reply){
  console.log(status, reply)
}).catch(function(err){
  console.log(err)
})

This outputs: 200 undefined

Whereas, using the traditional callback style:

client.account(function(status, reply){
  console.log(status, reply)
})

This outputs : 200 {{ json }}

Any ideas?

Upvotes: 0

Views: 63

Answers (2)

robertklep
robertklep

Reputation: 203419

The original callback is called with two arguments: status and reply.

Your promisifier is replacing that callback with resolve, which will therefore also get called with two arguments, and since it only takes one, the second argument gets lost (hence the undefined).

Try this instead:

args.push(function() { resolve([].slice.call(arguments)) });

This will cause resolve to be called with an array containing the arguments with which the callback was called, for which Bluebird has the (optional) .spread() method:

client.accountAsync().spread(function(status, reply){
  console.log(status, reply)
}).catch(function(err){
  console.log(err)
})

If you use .then(), it would receive the array as first argument.

Upvotes: 1

Amit
Amit

Reputation: 46341

The Promises/A+ standard defines the resolve & "onFulfilled" functions as accepting a single argument, the resolved value. Likewise, the single return value of onFulfilled is further propagated to the following onFulfilled function (attached via then).

client.accountAsync().then(function(status, reply){

tries to receive two augments but that is not possible, hence when logging reply undefined is logged.

Upvotes: 1

Related Questions