概述
async.parallelLimit
方法在文档中位于 Controll Flow
章节,表明这个方法是用来做流程控制的,async.eachLimit
方法位于 Collections
章节,表明这个方法是用来做数据处理的。在实际开发中我们可以使用这两个方法来完成同样的工作,下面我们就以给 26 位用户发送邮件这个任务来举例。
使用 async.parallelLimit 方法实现
async.parallelLimit
方法接受两个参数,第一个参数为任务数组,每个任务是一个函数,第二个参数为每次并行执行的任务数,第三个参数为回调函数。使用 async.parallelLimit
完成发送邮件任务的思路是先使用数据与所要做的任务,组装成任务数组交给 async.parallelLimit
方法去执行。
let userEmailList = [ 'a@example.com', 'b@example.com', ..., 'z@example.com' ];
let limit = 5;
let taskList = userEmailList.map(function (email) {
return function (callback) {
sendEmail(email, function (error, result) {
return callback(error, result);
});
}
});
async.parallel(taskList, limit, function (error, result) {
console.log(error, result);
});
使用 async.eachLimit 方法实现
async.eachLimit
方法接受四个参数,第一个参数为原始数据数组,第二个参数为每次并行处理的数据量,第三个参数为需要为数据进行的处理,第四个参数为回调函数。使用 async.eachLimit
完成发送邮件任务的思路是定义一个对数据进行处理的函数,然后使用 async.eachLimit
将处理函数应用所有数据上。
let userEmailList = [ 'a@example.com', 'b@example.com', ..., 'z@example.com' ];
let limit = 5;
let processer = function (email) {
sendEmail(email, function (error, result) {
return callback(error, result);
});
}
async.eachLimit(userEmailList, limit, processer, function (error){
console.log(error);
});
通过以上代码和 async 文档 可以看出 each
系列函数最终的回调函数是没有运行结果的,所以每一次 processor
中的结果需要另行存储处理。
总结
通过对比以上两种方案,很容易发现 async.parallelLimit
与 async.eachLimit
的区别与应用场景,async.parallelLimit
作为流程控制方法,应该应用于并发处理不同的任务并返回结果,async.eachLimit
作为数据处理方法,应该应用于并发地对一批数据进行相同的处理。所以显然对于给 26 为用户发送邮件这个任务应该使用 async.eachLimit
方法来实现。
在应用场景选择恰当的情况下很少使用到 async.parallelLimit
方法,使用 async.parallel
就可以了,毕竟任务数量不会非常巨大,不做限制一次性并行执行也不会有太大问题。但是如果使用不当,用作数据处理,数据的量级可能会非常巨大,如果不做并行数量限制显然是不可取的方式。
因为对于这两个方法理解地不够透彻,并且受到 Promise.all
使用方式的影响,很多历史代码中从未出现过 async.eachLimit
,都是使用 async.parallelLimit
配合 map
笨拙的实现了功能,特此写下此篇文章作为记录。