2017-04-24 48 views
2

我正在学习节点learnyounode exercises from nodeschool。 在第八锻炼他们要求编写一个程序,执行以下操作:Node.js中的异步http.get调用(Learyounode练习)

  • 需要三个URL作为参数,从反应
  • 收集数据,
  • 它们打印到控制台的顺序相同参数。

他们简单地提到了异步库的存在,这有助于计算回调,但他们也会邀请他们在没有他们的情况下完成练习。我的初步解决方案如下:

var http = require('http'); 
var bl = require('bl'); 
var results = Array(); 
var count = 0; 

function printResults() { 
    for (var i = 0; i < 3; i++) { 
     console.log(results[i]); 
    } 
} 


for (var index = 0; index < 3; index++) 
    http.get(process.argv[2+index], function(response) { 
     response.pipe(bl(function(err,data){ 
      if(err) console.error(err) 
      results[index] = data.toString(); 
      count++; 

      if(count==3) printResults(results); 
     })); 
    }); 
} 

但是,由于某种原因,这会打印三次“未定义”。我碰巧找到了正确的解决方案,只需用一个函数替换for循环,并将该函数的调用封装在另一个for循环中即可。

(...) 


function httpGet (index) { 
    http.get(process.argv[2+index], function(response) { 
     response.pipe(bl(function(err,data){ 
      if(err) console.error(err) 
      results[index] = data.toString(); 
      count++; 

      if(count==3) printResults(results); 
     })); 
    }); 
} 

for (var i = 0; i < 3; i++) 
    httpGet(i) 

不过,我不明白正是这种差异是如何做出的解决方案的工作。任何人都可以请赐教吗?

回答

4

在你的代码通过参考变量,你在回调时被调用时都会迭代所以等于3。请参阅下面的例子:

编辑:我忘了,总之,你的代码不会因为工作回调将所有设定结果的结果数组的索引3和你打印出指数从0到2

for(var index = 0; index < 3; index++){ 
 
    setTimeout(function(){ 
 
    console.log(index); 
 
    }, 500); 
 
}

通过创建函数出来的,你要添加更多的余地:

function fun(index){ 
 
    setTimeout(function(){ 
 
    console.log(index); 
 
    }, 500); 
 
} 
 

 
for(var index = 0; index < 3; index++){ 
 
    fun(index); 
 
}

您仍然可以使用匿名函数,但你需要有这样一个范围,围绕着它:

for(var index = 0; index < 3; index++){ 
 
    setTimeout((function(index){ 
 
    return function(){ 
 
     console.log(index); 
 
    }  
 
    })(index), 500); 
 
}

要尽量做到更清楚一点我会让变量名称与范围有所不同:

for(var outerIndexVariable = 0; outerIndexVariable < 3; outerIndexVariable++){ 
 
    setTimeout((function(innerIndexVariable){ 
 
    return function(){ 
 
     console.log(innerIndexVariable); 
 
    }  
 
    })(outerIndexVariable), 500); 
 
}