2013-11-21 107 views
2

所以我试图升级现有的api来支持承诺,但我想保持向后兼容性。所以,让我们说,这是我的API:创建一个接受回调的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); 
    } 
} 

所以新的来访者可以利用承诺的支持,但如果你在回调中传递的一切仍然有效。

这是一种由例如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; 
    }) 
} 

回答

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

是的,但是与上面的例子相比,这是一个样板。我不想在所有地方都这样做。 – bluepnume

相关问题