learnyounode - Juggling Async - 不同的顺序

时间:2017-02-05 14:16:22

标签: javascript node.js

这是来自node.js上的learnyounode教程练习9。我无法理解为什么我的代码没有按顺序打印出数据。

let http = require('http'),
    bl = require('bl'),
    urlArray = [process.argv[2], process.argv[3], process.argv[4]]
    results = []
    //counter = 0;

function collectData(i) {
    http.get(urlArray[i], (res) => {
        res.pipe(bl((err, data) => {
            if (err) {
                return console.log(err);
            }
            data = data.toString();
            results[i] = data;
            //counter++;

            //if (counter === 3) {
              if (results.length === 3) {
                results.forEach((result) => {
                    console.log(result);
                })
            }
        }))
    })
}

for (let i = 0; i < urlArray.length; i++) {
    collectData(i);
}

for循环应该从第一个url开始,然后按顺序转到最后一个url。根据我的理解,无论在循环的当前迭代中发生什么,都必须解决循环移动到下一次迭代。但是,结果似乎是随机的。如果我在命令行上运行我的解决方案,有时结果是有序的,有时它们不是。

编辑:这是我现有的解决方案。我添加了计数器变量并将http请求放入函数中。

2 个答案:

答案 0 :(得分:0)

每次运行得到不同结果的原因是因为http的get函数是异步实现的(异步)。您按正确的顺序执行请求,但get-URL上的Web服务器不会立即响应。

基本上,如果你有两个要调用的URL:

http://stackoverflow.com

http://google.com

你按照这个顺序调用它们,但google有一个很好的响应时间,比如10ms,stackoverflow需要更长的时间,比如20ms,你的google回调函数最初被调用,然后是stackoverflow的回调函数。

每次运行的响应时间可能不同,这就是每次运行时遇到不同结果的原因。

这是你的回调函数:

res.pipe(bl((err, data) => {
    if (err) {
        return console.log(err);
    }
    data = data.toString();
    console.log(data);
}

答案 1 :(得分:0)

整个问题是变量“i”和异步调用。使用此特定逻辑,由于异步调用,您无法控制i的值。

为了解你的代码问题,在行之后打印console.log: 结果[i] =数据;

这是我解决问题的方法:

for x in zip(*group_basket[::-1]):
    print('\t'.join(x))

# which prints:
# --------------------
# abcM1  abcL1    -
#  -     aefL2    -
# xyzM3   -      aefK3