我想异步迭代一个数组来解除阻塞执行。我正在使用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推迟执行。但为什么不呢?
答案 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
。
但是,此任务过于简单。为什么一个人需要异步循环?
并行执行异步任务。首先,由于每个任务都是异步的,因此无论如何都不会在同一个事件循环迭代中触发callback
,而是将其赋予特定的异步任务。其次,async.parallel
更适合这类任务。
执行一些CPU密集型任务,避免冻结事件循环(以便Node可以在迭代之间处理某些任务)。这就是我在上面的代码示例中假设的内容。使用普通JS(及其内置Array.prototype.forEach
)来完成此任务将非常困难,因为您需要以某种方式实现对事件的所有迭代的处理的检测。
答案 1 :(得分:1)