3

我想异步迭代一个数组以解除阻塞执行。我正在使用 caolan/async 来实现这一点。测试此代码时:

var ASync = require('async');

var arr = [];
for (var i = 0; i< 10; i++) {
    arr[i] = i;
}

var buf = "howdy";
ASync.forEach(arr, function(item, callback) {
    buf += item;
    callback();
}, function(err) {
    console.log(buf); // in the end
});
buf += "finished";

它显示了这个结果:

howdy0123456789

我认为它应该显示

howdyfinished0123456789

因为我希望异步库推迟执行。但为什么不是呢?

4

2 回答 2

4

在您的代码中,callback在与自身相同的事件循环迭代中执行foreach。由于您永远不会超出当前的事件循环迭代,因此buf += "finished"仅在执行完所有操作后才buf += item执行。

正确的版本是

var ASync = require('async');

var arr = [];
for (var i = 0; i< 10; i++) {
    arr[i] = i;
}

var buf = "howdy";
ASync.forEach(arr, function(item, callback) {
    process.nextTick(function () {
        buf += item;
        callback();
    });
}, function(err) {
    console.log(buf); // in the end
});
buf += "finished";

最后,buf意志等于howdy0finished123456789

但是,这项任务过于简单化了。为什么需要异步循环呢?

  1. 并行执行异步任务。首先,由于每个任务都是异步的,因此无论如何您都不会callback在同一个事件循环迭代中触发它,而是将其交给特定的异步任务。二async.parallel是比较适合这类任务。

  2. 执行一些 CPU 密集型任务,避免冻结事件循环(以便 Node 可以在迭代之间处理一些任务)。这就是我在上面的代码示例中所假设的。使用普通的 JS(及其内置Array.prototype.forEach)来完成这项任务将非常困难,因为您需要以某种方式实现对事件的检测,循环的所有迭代都已处理。

于 2012-08-21T10:10:56.213 回答
1

我认为您应该阅读以下内容:http: //howtonode.org/understanding-process-next-tick

于 2012-08-21T10:18:27.140 回答