learnyounode:杂乱的异步问题

时间:2017-05-25 14:09:21

标签: javascript node.js

我正在尝试解决learnyounode的杂耍异步问题。

以下是我的尝试。但我没有得到理想的输出。我可以通过在谷歌搜索找到解决方案。但我想要的是学习节点基础知识。有人可以指导我出错的地方吗?

var http = require('http');
var bl = require('bl');
var output = [];
var cnt = 0;

for (var i in process.argv) {
  if (i > 1 ) {
    http.get(process.argv[i],function(response){
      response.pipe(bl(function(err,data){
        output[cnt] = data.toString();
        cnt++;
        if (output.length === (process.argv.length - 2)) {
          printResult(output);
        }
      }));
    });
  }
}

function printResult(output){
  for (var i = 0; i < output.length; i++) {
    console.log(output[i]);
  }
}

我得到的输出:

  
      
  1. ACTUAL:“shazza给我们带来了一些开膛手的那些砖砌的东西。来一条带着小辫子的小辫子。你这个小小的开膛手   腐烂的伴侣可以得到一些larrikin。 “
  2.   
  3. 预料到:“shazza给我们带来了一些开膛手的那块砖头。带着一条小辫子,小心翼翼地注意着那个小小的开膛手。你的小开膛手   腐烂的伴侣可以得到一些larrikin。 “

  4.   
  5. ACTUAL:“当她是正确的澳大利亚规则时,请注意空中乒乓球。他没有一个战斗伙伴让投掷战斗机。   “

  6.   
  7. 预计:“像野蛮一样建造起来就像一个笨蛋一样引人注目。像我的公主一样,把我的公寓弄得像个傻瓜一样。   mokkies没有担心shazza让我们有些摇摇欲坠。 “

  8.   
  9. 实际:“像野蛮一样建造,不用担心会像一个笨蛋一样突出。像我的公主一样,把我的公寓弄出来。   mokkies没有担心shazza让我们有些摇摇欲坠。 “

  10.   
  11. 预期:“当她正确地说澳大利亚规则时,请注意空中乒乓球。他没有一个战斗伙伴让投掷战斗机。   “

  12.   
  13. ACTUAL:“”

  14.   
  15. 预期:“”
  16.   

1 个答案:

答案 0 :(得分:2)

如果我没有正确记住问题,您必须按照命令行参数中提供的URL的顺序打印响应。

您的解决方案的问题在于您实际上并未以正确的顺序存储您的回复 这部分代码:

// ...
output[cnt] = data.toString();
cnt++;
// ....

您异步触发了三个http请求,并使用计数器output将响应保存在cnt数组中。由于响应可以按任何顺序到达,因此无法保证响应将以与触发请求相同的顺序保存。例如,如果请求第3个响应首先出现,它将存储在0数组中的索引output,这不是您想要的。

解决此问题而不是使用独立计数器。使用用于触发http请求的现有变量i。因此,对于请求1,响应将保存在索引0处,因为请求2响应将保存在索引1处,依此类推。

在单独的函数中写下http get请求并传递索引i并使用此索引i保存您的回复。

//....
for (var i in process.argv) {
    if (i > 1) {
        httpGet(i);
    }
}


function httpGet(index) {
    http.get(process.argv[index], function(response) {
        response.pipe(bl(function(err, data) {
            output[index - 2] = data.toString();
            cnt++;
            // Use cnt to decide if all the responses have arrived and then print
            if (cnt === (process.argv.length - 2)) {
                printResult(output);
            }
        }));
    });
}
// .....

http get请求需要包装在一个单独的函数中,否则,响应块的匿名函数内的变量i的值对于每个函数都是相同的(在这种情况下将是4) 。这是典型的封闭问题。我建议你阅读这些内容以获得详细解释:

JavaScript closure inside loops – simple practical example

Creating closures in loops: A common mistake

如果这对您有用,请告诉我。