嵌套异步循环推送到不调用主回调的异步队列

时间:2014-07-26 21:03:14

标签: javascript node.js asynchronous

我有一个异步队列,我正在推动它会做什么。我生成需要进入的项目的方法是通过几个嵌套列表形成一个数据对象。队列最终会处理所有内容但由于某种原因我无法使用console.log('All done.')进入主回调。我删除了大多数不必要的东西,只是留下了异步的东西。我究竟做错了什么?我错过了什么吗?

var q = async.queue(function(task, callback) {
  console.log('hello ' + task);
  callback();
}, 2);

function A(data) {
  B(data, function() {
    // THIS ISN'T getting called. 
    console.log('All done.');
  })
}

function B(data, callback1) {
  var list = [[1,2], [3,4], [5,6]];
  async.each(list, function(item, callback1) {
    async.each(item, function(i, callback2) {
      doWork(i, function() {
        console.log('Work done');
      })
      callback2();
    }, 
    // THIS should be called when everything in this each is done. 
    callback1)
  })
}

function doWork(i, callback3) {
  q.push(i, callback3);
} 

1 个答案:

答案 0 :(得分:1)

这是带有一些注释的代码,因为讨论回调的回调有点复杂:

function B(data, callback1 //this is what you want to be called) {
  var list = [[1,2], [3,4], [5,6]];

  //async1
  async.each(list, function(item, callback1 //now callback1 is a function passed to your code by `async.each` not the original callback1) {
      //async2 
      async.each(item, function(i, callback2) {
      doWork(i, function() {
        console.log('Work done');
      })
      callback2();
    }, 
    // THIS is actually called, it's just a different function than you think it is 
    callback1)
  })
}

问题是您对B的参数和async1回调函数的回调参数使用了相同的名称。

因此async1回调中的callback1隐藏了外部callback1,实际上是内部async1回调,用于将控制权传递回async.each

解决方案很简单:重命名async1回调参数,例如:

function B(data, callback1) {
  var list = [[1,2], [3,4], [5,6]];
  async.each(list, function(item, async1_callback) { //here lies the rename
    async.each(item, function(i, callback2) {
      doWork(i, function() {
        console.log('Work done');
      })
      callback2();
    }, 
    // this is now called as expected 
    callback1
    ); 
    // BUT we forgot to call the async1_callback, so let's do it:
    async1_callback();

};

按预期工作。