2013-11-21 76 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

相關問題