需求:写一个程序,能接受3个url作为参数,并打印出这几个url返回的值。
思路:通过计算异步函数调用次数来匹配他们之间输入输出的顺序。
原本我设置了index来计数,每当后台返回的数据存入result数组的时候,就让index加1,等于3的时候意味着3个url都返回了值,然后把result输出。但是,最终result中成员的顺序,总是跟参数的顺序不一样。。。
var bl = require("bl");
var http = require('http');
var result = [];
var index = 0;
function getHtp(srcUrl){
http.get(srcUrl,function(res){
res.pipe(bl(function(err,data){
if(err){
console.log('err',err)
} else {
result[index] = data.length;
index++;
}
if(index == 3){
console.log(result)
}
}))
})
}
for(var i=0;i<3;i++){
getHtp(process.argv[i+2])
}
后来看到别人的写法,回调函数中返回另一个函数,此函数处理返回值的。这样就可以,result中的成员顺序和参数顺序就是一致的。我觉得我们的思路是一样的,为何这样的写法就能保证输出顺序,而我的写法就不能呢?另外,bl是一个npm包,用来处理buffer的。
var http = require('http')
var bl = require('bl')
var urls=process.argv.slice(2)
var out = []
var done= 0
for (var i = 0; i < urls.length; i++) {
http.get(urls[i],function(index){
return function(response){
response.pipe(bl(function(err,data){
out[index] = data.length
done+=1
if (done==3){
for (var i = 0; i < out.length; i++) {
console.log(out[i])
}
}
}))
}
}(i))
}
别人用了闭包,让返回值和存储关系对应起来了,你没有用,仅仅是简单的计数,根据返回先后展示结果,当然不对。
别人闭包的关键代码就是
部分代码,它让每次
http.get
都是调用顺序相关的。