在不使用异步库助手类的情况下,在node.js中进行for循环的异步

时间:2015-03-17 01:05:14

标签: 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

似乎数据已正确获取并存储在“数据”中。数组,但它仍然显示未定义。 知道为什么会这样吗? 提前谢谢!

1 个答案:

答案 0 :(得分:1)

这是node.js甚至浏览器中异步编程中非常常见的问题。您遇到的一个主要问题是循环变量i将不会是您希望它在调用异步回调后的某个时间。到那时,for循环将运行到其循环的末尾,i将位于所有响应回调的结束值。

有很多方法可以解决这个问题。您可以在close值上使用i的闭包,并使其唯一可用于每个回调。

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,因为它们非常非常方便地控制异步操作​​的流程和顺序。