【问题标题】:Create an api which accepts a callback, and also returns a promise创建一个接受回调的 API,并返回一个 Promise
【发布时间】:2013-11-23 04:25:52
【问题描述】:

所以我正在尝试升级现有的 API 以支持 Promise,但我想保持向后兼容性。所以,假设这是我的 api:

module.exports = {

    deliverPost: function(callback) {

        someAsyncFunction(function(err) {

            if (err)
                console.log(err);

            callback(err);
        });
    }
}

太好了,我可以调用它并传递回调,一切正常。

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

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

【问题讨论】:

    标签: javascript node.js promise q


    【解决方案1】:

    答案是使用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】:

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

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

      【讨论】:

      • 是的,但是与上面的示例相比,这是很多样板文件。我不想到处都这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多