关于Nodejs async模块的eachLimit方法的疑问
关于Nodejs async模块的eachLimit方法的疑问
感觉你是对的. 稍微修改下作者的代码, 也可以验证:
var async = require('async');
var arr = [{name:'#1', delay: 100}, // 修改了下delay的值
{name:'#2', delay: 800}, // #2 的delay 设置得较长
{name:'#3', delay: 100},
{name:'#4', delay: 200},
{name:'#5', delay: 300},
{name:'#6', delay: 400}];
var t = new Date(); // 记录个时间
async.eachLimit(arr, 2, function(item, callback) {
log('1.5 enter: ' + item.name + ' - ' + item.delay);
setTimeout(function(){
log('1.5 handle: ' + item.name);
callback(null, item.name);
}, item.delay);
}, function(err) {
log('1.5 err: ' + err);
});
function log(msg) {
console.log('%s> %s', pad(new Date() - t, 4), msg);
}
function pad(n, width, z) { // 前缀一些'0'
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
程序输出为:
0007> 1.5 enter: #1 - 100 0009> 1.5 enter: #2 - 800 0110> 1.5 handle: #1 0110> 1.5 enter: #3 - 100 0211> 1.5 handle: #3 0212> 1.5 enter: #4 - 200 0412> 1.5 handle: #4 0412> 1.5 enter: #5 - 300 0713> 1.5 handle: #5 0713> 1.5 enter: #6 - 400 0810> 1.5 handle: #2 1114> 1.5 handle: #6 1115> 1.5 err: undefined
可以看到#2在队列中很久, #3, #4和#5都执行完后, #2才执行完.
关于Node.js async模块的eachLimit方法的疑问
在使用Node.js的async
模块时,eachLimit
方法是一个非常有用的工具,它可以限制并发执行的任务数量。下面我们将通过一个具体的例子来理解 eachLimit
方法的工作原理。
示例代码
var async = require('async');
var arr = [
{name:'#1', delay: 100}, // 修改了下delay的值
{name:'#2', delay: 800}, // #2 的delay 设置得较长
{name:'#3', delay: 100},
{name:'#4', delay: 200},
{name:'#5', delay: 300},
{name:'#6', delay: 400}
];
var t = new Date(); // 记录个时间
async.eachLimit(arr, 2, function(item, callback) {
log('1.5 enter: ' + item.name + ' - ' + item.delay);
setTimeout(function(){
log('1.5 handle: ' + item.name);
callback(null, item.name);
}, item.delay);
}, function(err) {
log('1.5 err: ' + err);
});
function log(msg) {
console.log('%s> %s', pad(new Date() - t, 4), msg);
}
function pad(n, width, z) { // 前缀一些'0'
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
输出结果
0007> 1.5 enter: #1 - 100
0009> 1.5 enter: #2 - 800
0110> 1.5 handle: #1
0110> 1.5 enter: #3 - 100
0211> 1.5 handle: #3
0212> 1.5 enter: #4 - 200
0412> 1.5 handle: #4
0412> 1.5 enter: #5 - 300
0713> 1.5 handle: #5
0713> 1.5 enter: #6 - 400
0810> 1.5 handle: #2
1114> 1.5 handle: #6
1115> 1.5 err: undefined
解释
-
并发限制:
eachLimit
方法的第一个参数是数组,第二个参数是并发限制的数量(这里是2)。这意味着在任何时刻,最多只有两个任务会被同时处理。 -
任务执行顺序:尽管
#2
的延迟较长(800ms),它仍然会在#1
执行完毕之后立即被加入到队列中。但由于并发限制为2,#3
和#4
在#1
和#2
之后立即被添加到队列中,并且在#2
完成之前就完成了处理。 -
完成顺序:从输出结果可以看出,
#2
被推迟了一段时间(直到#3
,#4
, 和#5
都完成后),因为它受到并发限制的影响。
通过这个例子,我们可以看到 eachLimit
方法如何有效地管理并发任务,确保不会因为某些任务的延迟而导致其他任务被长时间阻塞。
async.eachLimit
方法是 async
库中的一个函数,它允许你在给定数组上并行执行任务,并且可以限制同时运行的任务数量。这样可以防止因同时处理大量任务而导致的性能问题或资源耗尽。
根据你提供的代码和描述,async.eachLimit
正确地限制了并发的任务数为2。这意味着在任何时候最多有两个任务在并行执行。一旦其中一个任务完成,下一个任务才会开始执行。
在你的例子中,当数组中的每个对象被处理时,它会模拟延迟(通过 setTimeout
)。由于 async.eachLimit
将并发数限制为2,第一个两个任务(即处理 #1
和 #2
的任务)几乎同时开始执行。然而,由于 #2
的延迟时间更长(800毫秒),因此它比其他任务花费的时间更长。这导致在 #2
完成之前,其他的任务(如 #3
, #4
, #5
)已经开始并完成它们的工作。
最终,所有任务都被处理完毕,async.eachLimit
回调函数在所有任务完成后被调用,错误参数 err
为 undefined
,表示没有发生错误。
以下是对这段代码的简化解释:
- 限制并发数:通过设置
async.eachLimit
的第三个参数为2,确保同时最多只有两个任务在运行。 - 任务执行顺序:尽管
#2
的延迟最长,但一旦前两个任务启动,后续任务会立即排队等待,直到前面的任务完成。 - 输出结果:从输出可以看到,尽管
#2
最后完成,但由于async.eachLimit
控制了并发度,任务依然按照预期顺序依次处理完成。
如果你有任何具体的疑问或需要进一步说明的地方,请告诉我!