javascript - 学习你 Node : juggling async issue

标签 javascript node.js

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

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

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: "Gutful of brickie where shazza got us some ripper. Come a bunyip with watch out for the dinky-di. You little ripper rotten mate lets get some larrikin. "
  2. EXPECTED: "Gutful of brickie where shazza got us some ripper. Come a bunyip with watch out for the dinky-di. You little ripper rotten mate lets get some larrikin. "

  3. ACTUAL: "Watch out for the aerial pingpong when she'll be right aussie rules footy. He hasn't got a battler mate lets throw a battler. "

  4. EXPECTED: "Built like a feral no worries stands out like a bonzer. Come a grundies my flat out like a boardies. As dry as a mokkies no worries shazza got us some rock up. "

  5. ACTUAL: "Built like a feral no worries stands out like a bonzer. Come a grundies my flat out like a boardies. As dry as a mokkies no worries shazza got us some rock up. "

  6. EXPECTED: "Watch out for the aerial pingpong when she'll be right aussie rules footy. He hasn't got a battler mate lets throw a battler. "

  7. ACTUAL: ""

  8. EXPECTED: ""

最佳答案

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

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

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

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

解决此问题而不是使用独立计数器。使用现有变量i用于触发 http 请求。因此,对于请求 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 的值响应 block 的匿名函数内部对于每个函数都是相同的(在本例中为 4)。这是经典的闭包问题。我建议您阅读这些以获得详细的解释:

JavaScript closure inside loops – simple practical example

Creating closures in loops: A common mistake

请告诉我这是否对您有用。

关于javascript - 学习你 Node : juggling async issue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44182656/

相关文章:

node.js - 在 NodeJS 中使用异步函数进入循环?

node.js - 带路径重写的 Nginx 代理配置

node.js - 限制登录访问 - Passport.js,Google 身份验证

javascript - 数据库中结果的数据列表

javascript - HTML5 Web Workers 在 Firefox 4 中工作,但在 Chrome 12.0.742.122 中不工作

javascript - 使 fetch 调用真正同步

javascript - ajax进度条图像隐藏和显示

javascript - 使用正则表达式 javascript 查找要终结的单词

node.js - 为什么 `yarn upgrade my_package` 升级时不考虑 package.json 中的版本

node.js - 读取 Jenkins 管道中的测试设置的环境变量