-1

在示例中:

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
4

1 回答 1

2

很多问题都源于这一行:

b("done");

这设置"done"为一个,err因为这就是第一个参数

迭代器传递了一个callback(err),一旦完成就必须调用它。如果未发生错误,则应在不带参数或显式空参数的情况下运行回调。

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

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

  1. 错误和未定义来自哪里?

    error来自callback:_

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

    然而undefined, 不是来自片段。不过,如果您使用的是 Node 的交互式 REPL,那么这将是源代码,因为它将显示eachLimitreturn值(即undefined)。

  2. 什么时候调用异步的回调?

    当 anerr被传递时, thecallback被提前调用。

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

    一旦 anerr被传递,async函数将停止迭代。eachLimit之所以成功,是因为它选择在停止之前6完成当前的“批处理”。


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

而且,要明确一点:async库不能使同步任务异步。它实际上假设任务已经是异步的,并且只是帮助管理其中的一组。

于 2013-07-12T06:13:23.317 回答