asynchronousin循环在node.js而不使用asynchronous库助手类

我是一个初学者node.js。 我正在尝试“learnyounode”教程中的示例。 我正在尝试编写一个程序,该程序需要三个url参数,并从这些url中获取一些数据,并按照提供url的顺序显示返回的数据。

var http = require('http'); var bl = require('bl'); var url = []; url[0] = process.argv[2]; url[1] = process.argv[3]; url[2] = process.argv[4]; var data = []; var remaining = url.length; for(var i = 0; i < url.length; i++){ http.get(url[i], function (response){ response.setEncoding('utf8'); response.pipe(bl(function (err, chunk){ if(err){ console.log(err); } else{ data[i] = chunk.toString(); console.log(data[i]); remaining -= 1; if(remaining == 0) { for(var j = 0; j < url.length; j++){ console.log(data[j]); } } } })); }); } 

我在程序中有两个console.log语句。 我得到的输出如下:

 It'll be chunder where lets throw a ford. We're going durry where mad as a cooee . Shazza got us some apples with come a strides. Mad as a swag when get a dog up y a roo. It'll be rapt piece of piss as cunning as a trackie dacks. As cross as a bogged with watch out for the boardies. As cunning as a digger fla min lets get some roo bar. As dry as a piker piece of piss he hasn't got a joey. Lets throw a strides mate we're going digger. undefined undefined undefined 

好像数据被正确地提取并存储在“数据”数组中,但仍然显示为未定义的。 任何想法为什么发生这种情况? 提前致谢!

这在node.js中甚至在浏览器中的asynchronous编程中是一个非常常见的问题。 你有一个主要的问题是循环variablesi不会是你想要的一段时间后asynchronouscallback被调用。 到那时, for循环将运行到其循环的结尾,并且i将处于所有响应callback的最终值。

有很多方法可以解决这个问题。 您可以使用闭包来close i值,并使其对每个callback都是唯一可用的。

 var http = require('http'); var bl = require('bl'); var url = []; url[0] = process.argv[2]; url[1] = process.argv[3]; url[2] = process.argv[4]; var data = []; var remaining = url.length; for(var i = 0; i < url.length; i++){ // create closure here to uniquely capture the loop index // for each separate http request (function(index) { http.get(url[index], function (response){ response.setEncoding('utf8'); response.pipe(bl(function (err, chunk){ if(err){ console.log(err); } else{ data[index] = chunk.toString(); console.log(data[index]); remaining -= 1; if(remaining == 0) { for(var j = 0; j < url.length; j++){ console.log(data[j]); } } } })); }); })(i); } 

如果你做了很多的node.js编程,你会发现你可能想学习如何使用promise,因为它们非常非常方便地控制asynchronous操作​​的stream程和顺序。