Javascript节点学校异步挑战.我把异步代码搞砸了



所有这些代码都在一个名为juggling_async.js的文件中。这是node school的练习9。

这个代码坏了(我写的):

var http = require('http');
var bl = require('bl');
var result = [];
var count = 0;
for(var i=0;i<3;i++) {
    http.get(process.argv[2 + i], function(res){
        res.pipe(bl(function(err,data){
            if(err) return console.log(err.message);
            result[i]  = data.toString();
            count++;
            if(count == 3) {
                for(var j=0;j<result.length;j++) {
                    console.log(result[j]);
                }
            }
        }));
    });
}

它注销:"未定义"
"未定义"
"未定义"
"[这是一个字符串]"

这个代码解决了问题:

var http = require('http')
var bl = require('bl')
var results = []
var count = 0
function printResults () {
  for (var i = 0; i < 3; i++)
    console.log(results[i])
}
function httpGet (index) {
  http.get(process.argv[2 + index], function (response) {
    response.pipe(bl(function (err, data) {
      if (err)
        return console.error(err)
      results[index] = data.toString()
      count++
      if (count == 3) // yay! we are the last one!
        printResults()
    }))
  })
}
for (var i = 0; i < 3; i++)
  httpGet(i)

在我看来,我的坏代码应该可以工作。我开始循环I,从0开始,我使用http库发出http.get请求,http.get进行回调,其中res是http.get要求的响应。函数(res)是在get请求返回之前不会运行的回调,对吗?此时,我仍然为0,所以我将data.toString()设置为result[0],对吗?结果数组的第一个元素应该包含正确的内容,而不是未定义的?

很明显,我的思想和代码都崩溃了。我错了该怎么办?

BTW:我读了关于闭包的相关帖子,我仍然不明白为什么我的代码被破坏了,或者它在哪里失败了。

在第一个例子中,变量i是一个引用,因此循环以i为最大值结束,然后调用所有回调并使用引用i,该引用将被设置为与for循环结束时相同的状态。

在第二个例子中,计数被保存到闭包中的另一个变量中。

最新更新