asynchronousstream和全局variables

我开始学习一些node.js和asynchronous事件玩杂耍,遇到了一个问题。

说我有n不同的node.jsstream可读,我可以得到。 每个产生我想要存储的data事件。 当所有的stream完成后,我想logging他们的所有结果在控制台。 我到目前为止:

 outputs = []; //Construct an array in which the outputs will wait for the streams to finish: for(var i = 0; i < n; i++){ outputs.push(''); } ended = 0; for(var i = 0; i < n; i++){ var ithReadable = getReadableStreamSomehow(i); // produces the i-th readable stream. ithReadable.on('data', function(chunk){ outputs[i] += chunk; }); ithReadable.on('end', function(chunk){ ended++; if (ended == n){ console.log(outputs); } }); } 

这个代码背后的想法是这样的:

对于从0n-1每个i ,代码开始监听第i个可读stream,产生2n监听stream的函数。 作为一个stream产生一个data事件,我想存储到第i个输出。 当所有的stream都完成后,我打印出他们的结果。

我提供的代码不起作用。 据我所知,问题是,当i从1改变到2时,写在第1stream上的函数现在要写到outputs[2]而不是outputs[1] ,使得上帝糟糕透顶。

我的问题是这样的:

我知道我想做的事情最好是通过pipe来实现。 但是,这是关于我学习asynchronous编程的原则,并希望通过这种方式推进。 我怎样才能避免像上面这样的情况全局variables( i )搞乱我的callback函数? 有没有办法做我想做的确切的事情(当然,但实际上)?

谢谢。

您需要在自己的作用域中声明一个不会被for循环修改的新variables。 我build议closures。

观察这两个asynchronous代码块之间的差异,并尝试在Chrome控制台中运行它们:

 for(var i = 0; i < 10; i++){ setTimeout(function(){ //This function is asynchronous. console.log(i); }, 1000); } 

版本2:

 for(var i = 0; i < 10; i++){ // This anonymous function executes immediately, once per loop, and is not asynchronous (function(){ var k = i; // once k is instantiated it will not be modified again. setTimeout(function(){ console.log(k); }, 1000); })(); } 

根据请求,不会在循环中创build多个函数的高效版本。 如果setTimeout在Node中传递第三个参数(传递给callback函数的参数),我们也可以在循环运行之前创buildsetATimeout使用的匿名函数。

 function setATimeout(i){ // i was passed by value since it is a primitive, so no scope problems. setTimeout(function(){ console.log(i); }, 1000); } for(var i = 0; i < 10; i++){ setATimeout(i); } 

我有个主意。 Javascript的函数构造函数允许你定义一个函数体作为一个string:

 ithReadable.on('data', new Function("chunk", "outputs[" + i + "] += chunk;"); 

文档: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function

尝试下面的代码。

在JavaScript中使用up-closure-scopevariables时应该小心。

Java需要闭包variables才是最终的价值。

与Java不同,Javascript允许修改闭包variables。

在这种情况下,您应该在某个对象内传递值而不是通过closuresvariables。

幸运的是,node.js在callback事件处理时传递“this”。

 ithReadable.idx = i; ithReadable.on('data', function(chunk){ outputs[this.idx] += chunk; }); 

使用IIFE版本跟进@AlexMA

 for(var i = 0; i < 10; i++){ // This anonymous function executes immediately, once per loop, and is not asynchronous (function(k){ //k is local it will not be modified. setTimeout(function(){ console.log(k); }, 1000); })(i); // pass i to anonymous function }