node.js:异步循环真的是异步的吗?

时间:2012-08-21 10:05:05

标签: node.js asynchronous

我想异步迭代一个数组来解除阻塞执行。我正在使用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

因为我希望Async lib推迟执行。但为什么不呢?

2 个答案:

答案 0 :(得分: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)来完成此任务将非常困难,因为您需要以某种方式实现对事件的所有迭代的处理的检测。

答案 1 :(得分:1)

相关问题