node.js 中的异步 for 循环而不使用异步库助手 类
async in for loop in node.js without using async library helper classes
我是 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
似乎数据已正确获取并存储在 'data' 数组中,但它仍然显示未定义。
知道为什么会这样吗?
提前致谢!
在 node.js 甚至浏览器中的异步编程中,这是一个非常常见的问题。您遇到的一个主要问题是循环变量 i
在调用异步回调后一段时间后将不是您想要的。到那时,for
循环将有 运行 循环结束,并且 i
将处于所有响应回调的结束值。
有很多方法可以解决这个问题。您可以在 i
值上使用 close
的闭包,并使其对每个回调唯一可用。
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编程,你会发现你可能想学习如何使用 promises,因为它们对于控制异步操作的流程和顺序非常非常方便。
我是 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
似乎数据已正确获取并存储在 'data' 数组中,但它仍然显示未定义。 知道为什么会这样吗? 提前致谢!
在 node.js 甚至浏览器中的异步编程中,这是一个非常常见的问题。您遇到的一个主要问题是循环变量 i
在调用异步回调后一段时间后将不是您想要的。到那时,for
循环将有 运行 循环结束,并且 i
将处于所有响应回调的结束值。
有很多方法可以解决这个问题。您可以在 i
值上使用 close
的闭包,并使其对每个回调唯一可用。
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编程,你会发现你可能想学习如何使用 promises,因为它们对于控制异步操作的流程和顺序非常非常方便。