为什么node.js的异步行为很奇怪?

时间:2013-07-12 05:55:55

标签: node.js asynchronous limit

在示例中:

async.eachLimit([1,2,3,4,5,6,7,8,9,10], 6, function(a, b) {
    console.log("current: " + a);
    b("done");
  },
  function(err) {
    if (err) {
      console.log("error");
    } else { 
      console.log("completely done");
    }
  }
);

输出:

current: 1
error
current: 2
current: 3
current: 4
current: 5
current: 6
undefined

为什么这么奇怪的行为?从哪里来的错误和未定义?其他4个元素在哪里处理?什么时候调用异步的回调? 正如我所料:

current: 1
done
current: 2
done
current: 3
done
current: 4
done
current: 5
done
current: 6
done
current: 7
done
current: 8
done
current: 9
done
current: 10
done
compeletely done

因此,同时只有6个元素处于活动状态。

我应该如何改变以获得我预期的异步行为?

更新

如果我使用

async.**eachSeries**([1,2,3,4,5,6,7,8,9,10], function(a, b) {
    console.log("current: " + a);
    b("done");
  },
  function(err) {
    if (err) {
      console.log("error");
    } else { 
      console.log("completely done");
    }
  }
);

然后输出也很奇怪:

current: 1
error
undefined

1 个答案:

答案 0 :(得分:2)

很多问题源于这一行:

b("done");

这将"done"设置为that's what the 1st arguments is以后的err

  

迭代器传递 callback(err) ,必须在完成后调用。如果没有发生错误,则应该在没有参数或显式空参数的情况下运行回调。

根据您按预期列出的输出,您可能需要:

console.log("done");
b(null); // or: `b()`

  1. 哪里出现错误并且未定义来自?

    error来自callback

    if (err) {
        console.log("error");
    }
    

    然而,undefined不是来自代码段。但是,如果您正在使用Node的交互式REPL,那么它将成为源,因为它将显示eachLimit的{​​{1}}值(return)。

    < / LI>
  2. 何时调用async的回调?

    undefined通过时,err会提前调用。

  3. 其他4个元素在哪里处理?

    一旦callback通过,err函数将停止迭代。 async只会转到eachLimit,因为它会选择在停止之前完成当前的“批次”。


  4. 至于6 vs eachLimit(),这取决于eachSeries()的作用。目前,iterator完全是同步的,因此两个函数的执行方式相似 - 一次迭代1个值。

    而且,要明确:iterator库不能使同步任务异步。它实际上假设任务已经是异步的,只是有助于管理它们中的一组。