Create an api which accepts a callback, and also returns a promise

余生颓废 提交于 2019-12-12 21:33:31

问题


So I'm trying to upgrade an existing api to support promises, but I want to maintain backwards compatibility. So, let's say this is my api:

module.exports = {

    deliverPost: function(callback) {

        someAsyncFunction(function(err) {

            if (err)
                console.log(err);

            callback(err);
        });
    }
}

That's great, I can call it and pass a callback, and everything works.

Now we do the same thing with promises:

var q = require('q');

module.exports = {

    deliverPost: function() {

        return q.nfcall(someAsyncFunction).catch(function(err) {

            console.log(err);
            throw err;
        });
    }
}

Great, now it returns a promise, but my problem is, any old clients of this api expect to be able to pass in a callback!

So what I really need is something like this:

var q = require('q');

module.exports = {

    deliverPost: function(callback) {

        return q.nfcall(someAsyncFunction).catch(function(err) {

            console.log(err);
            throw err;

        }).attachNodeStyleCallback(callback);
    }
}

So new callers can leverage the promise support, but everything still works if you pass in a callback.

This is a pattern used by, e.g. jQuery.ajax -- how can I do the same with Q.js?

Here's an implementation of attachNodeStyleCallback for reference:

q.makePromise.prototype.attachNodeStyleCallback = function(callback) {

    if (!callback)
        return this;

    return this.then(function(result) {

        callback(null, result);
        return result;

    }, function(err) {

        callback(err);
        throw err;
    })
}

回答1:


The answer is to use promise.nodeify:

var q = require('q');

module.exports = {

    deliverPost: function(callback) {

        return q.nfcall(someAsyncFunction).catch(function(err) {

            console.log(err);
            throw err;

        }).nodeify(callback);
    }
}



回答2:


You could just test for a callback and run the callback code if it is present:

var q = require('q');
module.exports = {

  deliverPost: function(callback) {
    if(typeof callback === 'function'){
      someAsyncFunction(function(err) {
        if (err)
          console.log(err);
        callback(err);
      });
    }else{
      return q.nfcall(someAsyncFunction).catch(function(err) {
        console.log(err);
        throw err;
      });
  }
}


来源:https://stackoverflow.com/questions/20132883/create-an-api-which-accepts-a-callback-and-also-returns-a-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!