创建一个接受回调的api,并返回一个promise

时间:2013-11-21 22:02:10

标签: javascript node.js promise q

所以我正在尝试升级现有的api来支持promises,但我想保持向后兼容性。所以,让我们说这是我的api:

module.exports = {

    deliverPost: function(callback) {

        someAsyncFunction(function(err) {

            if (err)
                console.log(err);

            callback(err);
        });
    }
}

那很好,我可以打电话给它并通过回调,一切正常。

现在我们用承诺做同样的事情:

var q = require('q');

module.exports = {

    deliverPost: function() {

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

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

很好,现在它返回了一个承诺,但我的问题是,这个api的任何旧客户都希望能够传递一个回调!

所以我真正需要的是这样的东西:

var q = require('q');

module.exports = {

    deliverPost: function(callback) {

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

            console.log(err);
            throw err;

        }).attachNodeStyleCallback(callback);
    }
}

所以新的调用者可以利用promise支持,但是如果传入回调,一切仍然有效。

这是一种模式,例如, jQuery.ajax - 我如何对Q.js进行同样的处理?

以下是attachNodeStyleCallback的实现,供参考:

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;
    })
}

2 个答案:

答案 0 :(得分:5)

答案是使用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);
    }
}

答案 1 :(得分:0)

您可以测试回调并运行回调代码(如果存在):

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;
      });
  }
}