2013-12-12 88 views
1

我刚刚开始使用JS和Node进行编程,但我还没有习惯于异步的东西。 基本上,我有以下代码:处理异步函数

for (var i=0, len=sources.length; i<len; i++) { 
    processSource(sources[i], function(info) { 
     doesOtherStuff(sources[i], info); 
    }); 
} 

它并没有真正的工作,因为,作为processSource需要一段时间才能完成,功能doesOtherStuff被调用时不匹配的参数,如sources[2]并将处理后的信息为sources[0]

处理这个问题的正确方法是什么?这些功能的设计是否有内在的错误? (processSource和doesOtherStuff都是我的功能)。

+1

“INT” hmmmm,看上去是错的。 – epascarello

+0

错字,对不起= P。问题依然存在。 –

+0

你告诉我一个使用javascript forEach的理由! – damphat

回答

2

代码的问题是,i不希望你期望它。

当循环完成时,函数级变量i的值为sources.length。所以,当内部函数使用什么时候运行这些内容。

for (var i=0, len=sources.length; i<len; i++) { 
    (function(i) { 
     processSource(sources[i], function(info) { 
      doesOtherStuff(sources[i], info); 
     }); 
    })(i); 
} 
+0

所以这实际上是标准的,难道它更像是一个代码被破坏的代码破解?我仍然试图让我的头脑围绕事件驱动。 –

+1

阅读http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem – epascarello

+1

该模式通常被称为IIFE(立即调用的函数表达式),以防您正在寻找更多关于它的信息。 –

0

1)使用var而不是int

2)您在processSource的电话中有多余的)

processSource(sources[i], function(info) /* No 2nd ')' here */ { 
    doesOtherStuff(sources[i], info); 
}); 

应该工作。

+0

对不起,这些都是拼写错误,其实不是问题。问题确实是Epascarello猜测的。 –

+0

为避免输入错误,您绝对不应该将*代码输入到SO中,而是从您的源代码中复制*。 –

+0

对不起...代码实际上有点复杂,所以我试图减少它对问题更清楚。猜猜它没有帮助 –

0

尝试使用Caolan's async library - 这适用于Node和浏览器。然后,您可以做这样的事情:

async.map(sources, function (item, callback) { 
    // Do your actions on each item here 
    processSource(item, function (info) { 
     var result = doOtherStuff(item, info); 

     // Send callback so the next item can be processed 
     callback(null, result); 
    }); 
}, function (err, results) { 
    // Handle the processed results here 
}); 
+0

这不是一个矫枉过正的?或者这个库在大多数节点项目中使用(如Boost库到C++)? –

1

JavaScript的风格可以帮助你:

sources.forEach(function (e) { 
    processSource(e, function(info) { 
     doesOtherStuff(e, info); 
    }); 
}