NodeJS:调用for循环内的callback函数

基本上,我试图调用一个函数,其中一个循环内运行许多callback函数(callback地狱)..如下所示:

for(var i=0;i<data.id.length;i++) { DAO.getUserById(data.id[i],function(err,resp1) { /* some other work based on resp1 */ DAO.getOtherData(resp1.username,resp1.userId,function(err,resp2) { /* similary some other work*/ }); }); } 

我在我的应用程序中的几个位置有相同的模式,有些时候我遇到了callback的问题,为循环克服,但callback不给响应,这似乎像DAO方法已被调用,但仍在等待响应。 有没有优化的方法来解决这个问题?

这将是很高兴知道是否有一些JavaScript编码模式可以解决这个问题(除了任何第三方库)谢谢

你听说过延期或承诺吗? 我想这就是你要找的。 它的基本forms基本上是一个有两个处理程序的对象。 一个失败,一个成功。

但是还有其他的帮助函数,比如那些可以让你以更可读的方式链接函数的函数。 看看q或jQuery的实现。 有关非常好的介绍,请阅读Async JavaScript。

编辑:/

我做了一个小工作的例子,因为JS为你捣鼓 。

  var data = { id : [] }; for(var i = 0; i < 10; i++) { data.id.push(i); } // DAO definition var DAO = { getUserById : function(id) { var deferred = $.Deferred(); setTimeout(function() { var isError = Math.floor(Math.random()*11) > 5; if(isError) { deferred.reject("WOW - Much Handler - So error"); } else { deferred.resolve({ username : 'Max', userId : id }); } }, 50); return deferred.promise(); }, getOtherData : function(username, userId) { var deferred = $.Deferred(); setTimeout(function() { deferred.resolve((username + ' id: ' + userId)); }, 20); return deferred.promise(); } }; function printResult(res) { $('#result').html($('#result').html() + '<br />' + res); }; // DAO usage for(var i=0;i<data.id.length;i++) { DAO.getUserById(data.id[i]) .done(function(res) { DAO.getOtherData(res.username, res.userId).done(function(result) { printResult(result); }); }) .fail(function(res) { printResult(res); }); } 

这样做的巨大优势是双重的:

  1. 您可以免费获得error handling程序代码和结果处理程序代码的分离
  2. 它阻止你嵌套地狱。 (callback,在callback中,在callback…)由于延期,你可以将实际的逻辑推断出来。
  3. 同步的callback变得非常容易,因为你只需要使用时 。

我使用jQuerys Deferreds,因为jsFiddle在下拉框中有jquery。 你可以使用任何你想要的实现。

当你有了实现它的概念时,你自己不应该太难。

你可以使用async.waterfall函数来处理你的问题。 所有函数都被串行调用,函数的结果作为参数发送到下一个函数。 以下是文档中的示例用法:

 async.waterfall([ function(callback){ callback(null, 'one', 'two'); }, function(arg1, arg2, callback){ callback(null, 'three'); }, function(arg1, callback){ // arg1 now equals 'three' callback(null, 'done'); } ], function (err, result) { // result now equals 'done' }); 

看看这个代码。

 var i=0; var length = data.id.length; var getData = function(index) { DAO.getUserById(data.id[index],function(err,resp1) { /* some other work based on resp1 */ DAO.getOtherData(resp1.username,resp1.userId,function(err,resp2) { /* similary some other work*/ index++; if(index < length) { getData(index); } }); }); } getData(i); 

这是你需要什么?