Nodejs async collections 介绍~
Nodejs async collections 介绍~
async是一个工具模块,其中方法有很多,主要分3大类(集合,流程控制,工具),今天就简单说说 集合 的一些常用方法
each(arr, iterator, callback)
很简单,看方法名就知道这是一个循环。
参数:
-
arr想要循环的数组 -
iterator(item, callback)一个回调函数,循环到的每一项都会调用这个函数。item数组中的每一项。callback(err)当完成的时候调用,应该不带参数执行,或者明确指定一个null -
callback(err)一个回调函数,用于循环完成后 或 发生错误时调用
这个循环与系统提供的for循环等是一样的。属于并行执行的循环,请看下面的例子:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.each(arr, iterator, function (err) {
console.log('err: ’ + err);
});
输出结果是:
start:a
start:b
start:c
end: b
end: a
end: c
err: undefined
先输出3个 start, 然后输出3个 end 注意顺序, 最后是 err
由此可以看出,它与正常的循环并无两样。
eachSeries(arr, iterator, callback)
语法与上面的用法一样。不同的是,上面我称为 并行执行的循环,而这个我称为,依次执行的循环,请看下面的例子:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.eachSeries(arr, iterator, function (err) {
console.log('err: ’ + err);
});
细心的同学可能已经发现问题了。这段代码与上面的代码几乎一模一样。唯一不一样的地方只有async.each 改成了 async.eachSeries
结果为:
start:a
end: a
start:b
end: b
start:c
end: c
err: undefined
看完结果同学们就可以理解,为什么称 eachSeries 为依次执行的循环了。
eachLimit(arr, limit, iterator, callback)
如果非要起一个名字的话。我称它为 分批执行 也可以说是 限制并行数量的循环
用法与上面大致一样。只不过多了一个参数 limit
limit限制并行的最大数量
看一下例子:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.eachLimit(arr, 1, iterator, function (err) {
console.log('err: ’ + err);
});
结果为:
start:a
end: a
start:b
end: b
start:c
end: c
err: undefined
可以看出,如果 limit 的为 1,那么就与 eachSeries 一样,一条一条依次执行。
如果 limit 的数量为 3 我们在试试:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.eachLimit(arr, 3, iterator, function (err) {
console.log('err: ’ + err);
});
输出结果为:
start:a
start:b
start:c
end: b
end: a
end: c
err: undefined
相信同学们已经看明白,我就不多做解释了。
map(arr, iterator, callback)
map 通俗点说,就是通过一个转换函数(iterator),把数组中的每个值映射到一个新的数组中。(产生一个新的数组)
参数:
-
arr想要循环的数组 -
iterator(item, callback)一个回调函数,循环到得每一项都会调用这个函数callback(err, transformed)当程序执行完时,调用此参数(必须调用此参数) -
callback(err, results)一个回调函数,当所有数组执行完成,或发生错误的时候,被调用。
例如:
function iterator (item, done) {
console.log( 'start:', item.name );
setTimeout(function () {
console.log( 'end:', item.name );
done(null, item.name += '!');
}, item.delay);
}
async.map(arr, iterator, function (err, result) {
console.log( 'err: ', err );
console.log( ‘result:’, result );
});
结果为:
start: a
start: b
start: c
end: b
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
mapSeries(arr, iterator, callback)
语法与上面 map 一样,不同的是,上面是 并行执行,而这个是 依次执行,与 each 和 eachSeries 的关系是一样的。
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log( ‘start:’, item.name );
setTimeout(function () {
console.log( ‘end:’, item.name );
done(null, item.name += ‘!’);
}, item.delay);
}
async.mapSeries(arr, iterator, function (err, result) {
console.log( 'err: ', err );
console.log( ‘result:’, result );
});
代码与 map 几乎一样。只是把 async.map 改成了 async.mapSeries,输出结果为:
start: a
end: a
start: b
end: b
start: c
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
从输出结构可以看出,它是依次执行的。
mapLimit(arr, limit, iterator, callback)
与 map 一样,但比 map 多了一个参数 limit 来限制并行的最大数量。
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log( ‘start:’, item.name );
setTimeout(function () {
console.log( ‘end:’, item.name );
done(null, item.name += ‘!’);
}, item.delay);
}
async.mapLimit(arr, 1, iterator, function (err, result) {
console.log( 'err: ', err );
console.log( ‘result:’, result );
});
limit 设置为 1 ,结果为:
start: a
end: a
start: b
end: b
start: c
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
结果与 mapSeries 一样,换成 2 结果为:
start: a
start: b
end: b
start: c
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
换成 3 结果为:
start: a
start: b
start: c
end: b
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
filter(arr, iterator, callback)
遍历 arr 中的每个值,返回包含所有通过 iterator 真值检测的元素值。这个操作是并行的,但返回的结果是顺序的。
参数:
-
arr一个数组,用于遍历 -
iterator(item, callback)一个函数,用于真值检测item数组中的每一项callback(truthValue)完成时调用,必须带一个布尔参数 -
callback一个回调函数,用于执行完成后,或发生错误时调用。
例如:
var arr = [ {n: 1, delay: 200}, {n: 2, delay: 100}, {n: 3, delay: 300}, {n: 4, delay: 500}, {n: 5, delay: 100} ];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n );
done( item.n > 2 );
}, item.delay);
}
async.filter(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
start: 2
start: 3
start: 4
start: 5
end: 2
end: 5
end: 1
end: 3
end: 4
result: [ { n: 3, delay: 300 }, { n: 4, delay: 500 }, { n: 5, delay: 100 } ]
filterSeries(arr, iterator, callback)
与上面 filter 类似,它是 依次执行。
var arr = [ {n: 1, delay: 200}, {n: 2, delay: 100}, {n: 3, delay: 300}, {n: 4, delay: 500}, {n: 5, delay: 100} ];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n );
done( item.n > 2 );
}, item.delay);
}
async.filterSeries(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
把 async.filter 改成 async.filterSeries 输出结果为:
start: 1
end: 1
start: 2
end: 2
start: 3
end: 3
start: 4
end: 4
start: 5
end: 5
result: [ { n: 3, delay: 300 }, { n: 4, delay: 500 }, { n: 5, delay: 100 } ]
reject(arr, iterator, callback)
reject跟filter正好相反,当检测为true时,抛弃之~~~
var arr = [ {n: 1, delay: 200}, {n: 2, delay: 100}, {n: 3, delay: 300}, {n: 4, delay: 500}, {n: 5, delay: 100} ];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n );
done( item.n > 2 );
}, item.delay);
}
async.reject(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
start: 2
start: 3
start: 4
start: 5
end: 2
end: 5
end: 1
end: 3
end: 4
result: [ { n: 1, delay: 200 }, { n: 2, delay: 100 } ]
rejectSeries(arr, iterator, callback)
如果说reject是并行(异步的)的,那么rejectSeries就是串行的(同步的),前面写了那么多 并行 和 串行 的比较例子,从现在往后就不举例说明了。
reduce(arr, memo, iterator, callback)
Reduce可以让我们给定一个初始值,用它与集合中的每一个元素做运算**(前一次的运算结果与下一个值做运算)**,最后得到一个值。reduce从左向右来遍历元素,如果想从右向左,可使用reduceRight。
加法运算:
var arr = [1, 3, 5];
function iterator (memo, item, done) {
console.log( memo, item );
setTimeout(function () {
done( null, item + memo );
}, 300);
}
async.reduce(arr, 2, iterator, function (err, result) {
console.log( ‘result:’, result );
});
输出结果为:
2 1
3 3
6 5
result: 11
乘法运算:
var arr = [1, 3, 5];
function iterator (memo, item, done) {
console.log( memo, item );
setTimeout(function () {
done( null, item * memo );
}, 300);
}
async.reduce(arr, 2, iterator, function (err, result) {
console.log( 'result:', result );
});
输出结果为:
2 1
2 3
6 5
result: 30
reduceRight(arr, memo, iterator, callback)
与 reduce 一样,不同的是,reduceRight 是从右向左计算。
detect(arr, iterator, callback)
用于取得集合中满足条件的第一个元素(并行执行)。
语法:
-
arr一个数组 -
iterator(item, callback)回调函数,用于处理逻辑(迭代器)item数组中的每一项callback(truthValue)程序完成后执行。必须传入布尔值。 -
callback(result)回调函数,iterator第一次返回true,或 循环完成后执行。
例如:
var arr = [
{n:1,delay:500},
{n:2,delay:200},
{n:3,delay:300}
];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n )
done( item.n > 1 );
}, item.delay );
}
async.detect(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
start: 2
start: 3
end: 2
result: { n: 2, delay: 200 }
end: 3
end: 1
可以看出,输出 2 的时候,就执行 callback(result) 了,也可以看出。detect是并行执行的。
detectSeries(arr, iterator, callback)
与 detect 类似。不过 detectSeries 是依次执行的。
例如:
var arr = [
{n:1,delay:500},
{n:2,delay:200},
{n:3,delay:300}
];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n )
done( item.n > 1 );
}, item.delay );
}
async.detectSeries(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
end: 1
start: 2
end: 2
result: { n: 2, delay: 200 }
sortBy(arr, iterator, callback)
对集合内的元素进行排序,根据每个元素进行某异步操作后产生的值,从小到大排序。
语法:
-
arr一个数组 -
iterator(item, callback)一个回调函数,循环到得每一项都会执行。item数组中的每一项callback(err, sortValue)完成时调用。 -
callback(err, results)一个回调函数,所有iterator完成后或发生错误时执行。
例1:
var arr = [2, 5, 9, 10, 22, 1, 7, 20];
function iterator (item, done) {
done( null, item );
}
async.sortBy(arr, iterator, function (err, result) {
console.log( result ); // [ 1, 2, 5, 7, 9, 10, 20, 22 ]
});
例2:
var arr = [2, 5, 9, 10, 22, 1, 7, 20];
function iterator (item, done) {
done( null, item * -1 );
}
async.sortBy(arr, iterator, function (err, result) {
console.log( result ); // [ 22, 20, 10, 9, 7, 5, 2, 1 ]
});
some(arr, iterator, callback)
判断集合中是否有至少一个元素满足条件,如果是最终callback得到的值为true,否则为false.
参数:
-
arr一个数组 -
iterator(item, callback)一个回调函数,循环到得每一项都会执行。callback(truthValue)必须传递一个布尔值。 -
callback(result)回调函数result为true或false取决于iterator的运行结果。
例1:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 10 );
}
async.some(arr, iterator, function (result) {
console.log( result ); // false
});
结果是 false,因为数组中,没有比10大的数。
例2:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 9 );
}
async.some(arr, iterator, function (result) {
console.log( result ); // true
});
结果是 true,因为 10 比 9 大。
every(arr, iterator, callback)
如果集合里每一个元素都满足条件,则传给最终回调的result为true,否则为false
例1:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 1 );
}
async.every(arr, iterator, function (result) {
console.log( result ); // true
});
例2:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 5 );
}
async.every(arr, iterator, function (result) {
console.log( result ); // false
});
concat(arr, iterator, callback)
将多个异步操作的结果合并为一个数组。
语法:
concat(arr, iterator(item,callback(err, result)), callback(err, result))
code:
var arr = [
{
list : [1,2,3,4],
delay : 200
},{
list : [5,6,7],
delay : 100
},{
list : [8,9],
delay : 300
}
];
function iterator (item, done) {
console.log( ‘start:’, item.list )
setTimeout(function () {
console.log( ‘end:’, item.list )
done( null, item.list );
}, item.delay);
}
async.concat(arr, iterator, function (err, result) {
console.log( result ); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
});
结果为:
start: [ 1, 2, 3, 4 ]
start: [ 5, 6, 7 ]
start: [ 8, 9 ]
end: [ 5, 6, 7 ]
end: [ 1, 2, 3, 4 ]
end: [ 8, 9 ]
[ 5, 6, 7, 1, 2, 3, 4, 8, 9 ]
通过结果,会发现。这是一个并行的操作。合并之后的顺序是不固定的。
concatSeries(arr, iterator, callback)
与 concat 类似,不过 concatSeries 是串行的。
code:
var arr = [
{
list : [1,2,3,4],
delay : 200
},{
list : [5,6,7],
delay : 100
},{
list : [8,9],
delay : 300
}
];
function iterator (item, done) {
console.log( ‘start:’, item.list )
setTimeout(function () {
console.log( ‘end:’, item.list )
done( null, item.list );
}, item.delay);
}
async.concatSeries(arr, iterator, function (err, result) {
console.log( result ); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
});
结果是:
start: [ 1, 2, 3, 4 ]
end: [ 1, 2, 3, 4 ]
start: [ 5, 6, 7 ]
end: [ 5, 6, 7 ]
start: [ 8, 9 ]
end: [ 8, 9 ]
[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]async是一个工具模块,其中方法有很多,主要分3大类(集合,流程控制,工具),今天就简单说说 集合 的一些常用方法
each(arr, iterator, callback)
很简单,看方法名就知道这是一个循环。
参数:
-
arr想要循环的数组 -
iterator(item, callback)一个回调函数,循环到的每一项都会调用这个函数。item数组中的每一项。callback(err)当完成的时候调用,应该不带参数执行,或者明确指定一个null -
callback(err)一个回调函数,用于循环完成后 或 发生错误时调用
这个循环与系统提供的for循环等是一样的。属于并行执行的循环,请看下面的例子:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.each(arr, iterator, function (err) {
console.log('err: ’ + err);
});
输出结果是:
start:a
start:b
start:c
end: b
end: a
end: c
err: undefined
先输出3个 start, 然后输出3个 end 注意顺序, 最后是 err
由此可以看出,它与正常的循环并无两样。
eachSeries(arr, iterator, callback)
语法与上面的用法一样。不同的是,上面我称为 并行执行的循环,而这个我称为,依次执行的循环,请看下面的例子:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.eachSeries(arr, iterator, function (err) {
console.log('err: ’ + err);
});
细心的同学可能已经发现问题了。这段代码与上面的代码几乎一模一样。唯一不一样的地方只有async.each 改成了 async.eachSeries
结果为:
start:a
end: a
start:b
end: b
start:c
end: c
err: undefined
看完结果同学们就可以理解,为什么称 eachSeries 为依次执行的循环了。
eachLimit(arr, limit, iterator, callback)
如果非要起一个名字的话。我称它为 分批执行 也可以说是 限制并行数量的循环
用法与上面大致一样。只不过多了一个参数 limit
limit限制并行的最大数量
看一下例子:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.eachLimit(arr, 1, iterator, function (err) {
console.log('err: ’ + err);
});
结果为:
start:a
end: a
start:b
end: b
start:c
end: c
err: undefined
可以看出,如果 limit 的为 1,那么就与 eachSeries 一样,一条一条依次执行。
如果 limit 的数量为 3 我们在试试:
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log(‘start:’ + item.name);
setTimeout(function(){
console.log('end: ’ + item.name);
done(null);
}, item.delay);
}
async.eachLimit(arr, 3, iterator, function (err) {
console.log('err: ’ + err);
});
输出结果为:
start:a
start:b
start:c
end: b
end: a
end: c
err: undefined
相信同学们已经看明白,我就不多做解释了。
map(arr, iterator, callback)
map 通俗点说,就是通过一个转换函数(iterator),把数组中的每个值映射到一个新的数组中。(产生一个新的数组)
参数:
-
arr想要循环的数组 -
iterator(item, callback)一个回调函数,循环到得每一项都会调用这个函数callback(err, transformed)当程序执行完时,调用此参数(必须调用此参数) -
callback(err, results)一个回调函数,当所有数组执行完成,或发生错误的时候,被调用。
例如:
function iterator (item, done) {
console.log( 'start:', item.name );
setTimeout(function () {
console.log( 'end:', item.name );
done(null, item.name += '!');
}, item.delay);
}
async.map(arr, iterator, function (err, result) {
console.log( 'err: ', err );
console.log( ‘result:’, result );
});
结果为:
start: a
start: b
start: c
end: b
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
mapSeries(arr, iterator, callback)
语法与上面 map 一样,不同的是,上面是 并行执行,而这个是 依次执行,与 each 和 eachSeries 的关系是一样的。
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log( ‘start:’, item.name );
setTimeout(function () {
console.log( ‘end:’, item.name );
done(null, item.name += ‘!’);
}, item.delay);
}
async.mapSeries(arr, iterator, function (err, result) {
console.log( 'err: ', err );
console.log( ‘result:’, result );
});
代码与 map 几乎一样。只是把 async.map 改成了 async.mapSeries,输出结果为:
start: a
end: a
start: b
end: b
start: c
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
从输出结构可以看出,它是依次执行的。
mapLimit(arr, limit, iterator, callback)
与 map 一样,但比 map 多了一个参数 limit 来限制并行的最大数量。
var arr = [ {name: 'a', delay: 200}, {name: 'b', delay: 100}, {name: 'c', delay: 300} ];
function iterator (item, done) {
console.log( ‘start:’, item.name );
setTimeout(function () {
console.log( ‘end:’, item.name );
done(null, item.name += ‘!’);
}, item.delay);
}
async.mapLimit(arr, 1, iterator, function (err, result) {
console.log( 'err: ', err );
console.log( ‘result:’, result );
});
limit 设置为 1 ,结果为:
start: a
end: a
start: b
end: b
start: c
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
结果与 mapSeries 一样,换成 2 结果为:
start: a
start: b
end: b
start: c
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
换成 3 结果为:
start: a
start: b
start: c
end: b
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
filter(arr, iterator, callback)
遍历 arr 中的每个值,返回包含所有通过 iterator 真值检测的元素值。这个操作是并行的,但返回的结果是顺序的。
参数:
-
arr一个数组,用于遍历 -
iterator(item, callback)一个函数,用于真值检测item数组中的每一项callback(truthValue)完成时调用,必须带一个布尔参数 -
callback一个回调函数,用于执行完成后,或发生错误时调用。
例如:
var arr = [ {n: 1, delay: 200}, {n: 2, delay: 100}, {n: 3, delay: 300}, {n: 4, delay: 500}, {n: 5, delay: 100} ];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n );
done( item.n > 2 );
}, item.delay);
}
async.filter(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
start: 2
start: 3
start: 4
start: 5
end: 2
end: 5
end: 1
end: 3
end: 4
result: [ { n: 3, delay: 300 }, { n: 4, delay: 500 }, { n: 5, delay: 100 } ]
filterSeries(arr, iterator, callback)
与上面 filter 类似,它是 依次执行。
var arr = [ {n: 1, delay: 200}, {n: 2, delay: 100}, {n: 3, delay: 300}, {n: 4, delay: 500}, {n: 5, delay: 100} ];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n );
done( item.n > 2 );
}, item.delay);
}
async.filterSeries(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
把 async.filter 改成 async.filterSeries 输出结果为:
start: 1
end: 1
start: 2
end: 2
start: 3
end: 3
start: 4
end: 4
start: 5
end: 5
result: [ { n: 3, delay: 300 }, { n: 4, delay: 500 }, { n: 5, delay: 100 } ]
reject(arr, iterator, callback)
reject跟filter正好相反,当检测为true时,抛弃之~~~
var arr = [ {n: 1, delay: 200}, {n: 2, delay: 100}, {n: 3, delay: 300}, {n: 4, delay: 500}, {n: 5, delay: 100} ];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n );
done( item.n > 2 );
}, item.delay);
}
async.reject(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
start: 2
start: 3
start: 4
start: 5
end: 2
end: 5
end: 1
end: 3
end: 4
result: [ { n: 1, delay: 200 }, { n: 2, delay: 100 } ]
rejectSeries(arr, iterator, callback)
如果说reject是并行(异步的)的,那么rejectSeries就是串行的(同步的),前面写了那么多 并行 和 串行 的比较例子,从现在往后就不举例说明了。
reduce(arr, memo, iterator, callback)
Reduce可以让我们给定一个初始值,用它与集合中的每一个元素做运算**(前一次的运算结果与下一个值做运算)**,最后得到一个值。reduce从左向右来遍历元素,如果想从右向左,可使用reduceRight。
加法运算:
var arr = [1, 3, 5];
function iterator (memo, item, done) {
console.log( memo, item );
setTimeout(function () {
done( null, item + memo );
}, 300);
}
async.reduce(arr, 2, iterator, function (err, result) {
console.log( ‘result:’, result );
});
输出结果为:
2 1
3 3
6 5
result: 11
乘法运算:
var arr = [1, 3, 5];
function iterator (memo, item, done) {
console.log( memo, item );
setTimeout(function () {
done( null, item * memo );
}, 300);
}
async.reduce(arr, 2, iterator, function (err, result) {
console.log( 'result:', result );
});
输出结果为:
2 1
2 3
6 5
result: 30
reduceRight(arr, memo, iterator, callback)
与 reduce 一样,不同的是,reduceRight 是从右向左计算。
detect(arr, iterator, callback)
用于取得集合中满足条件的第一个元素(并行执行)。
语法:
-
arr一个数组 -
iterator(item, callback)回调函数,用于处理逻辑(迭代器)item数组中的每一项callback(truthValue)程序完成后执行。必须传入布尔值。 -
callback(result)回调函数,iterator第一次返回true,或 循环完成后执行。
例如:
var arr = [
{n:1,delay:500},
{n:2,delay:200},
{n:3,delay:300}
];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n )
done( item.n > 1 );
}, item.delay );
}
async.detect(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
start: 2
start: 3
end: 2
result: { n: 2, delay: 200 }
end: 3
end: 1
可以看出,输出 2 的时候,就执行 callback(result) 了,也可以看出。detect是并行执行的。
detectSeries(arr, iterator, callback)
与 detect 类似。不过 detectSeries 是依次执行的。
例如:
var arr = [
{n:1,delay:500},
{n:2,delay:200},
{n:3,delay:300}
];
function iterator (item, done) {
console.log( ‘start:’, item.n );
setTimeout(function () {
console.log( ‘end:’, item.n )
done( item.n > 1 );
}, item.delay );
}
async.detectSeries(arr, iterator, function (result) {
console.log( ‘result:’, result );
});
输出结果为:
start: 1
end: 1
start: 2
end: 2
result: { n: 2, delay: 200 }
sortBy(arr, iterator, callback)
对集合内的元素进行排序,根据每个元素进行某异步操作后产生的值,从小到大排序。
语法:
-
arr一个数组 -
iterator(item, callback)一个回调函数,循环到得每一项都会执行。item数组中的每一项callback(err, sortValue)完成时调用。 -
callback(err, results)一个回调函数,所有iterator完成后或发生错误时执行。
例1:
var arr = [2, 5, 9, 10, 22, 1, 7, 20];
function iterator (item, done) {
done( null, item );
}
async.sortBy(arr, iterator, function (err, result) {
console.log( result ); // [ 1, 2, 5, 7, 9, 10, 20, 22 ]
});
例2:
var arr = [2, 5, 9, 10, 22, 1, 7, 20];
function iterator (item, done) {
done( null, item * -1 );
}
async.sortBy(arr, iterator, function (err, result) {
console.log( result ); // [ 22, 20, 10, 9, 7, 5, 2, 1 ]
});
some(arr, iterator, callback)
判断集合中是否有至少一个元素满足条件,如果是最终callback得到的值为true,否则为false.
参数:
-
arr一个数组 -
iterator(item, callback)一个回调函数,循环到得每一项都会执行。callback(truthValue)必须传递一个布尔值。 -
callback(result)回调函数result为true或false取决于iterator的运行结果。
例1:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 10 );
}
async.some(arr, iterator, function (result) {
console.log( result ); // false
});
结果是 false,因为数组中,没有比10大的数。
例2:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 9 );
}
async.some(arr, iterator, function (result) {
console.log( result ); // true
});
结果是 true,因为 10 比 9 大。
every(arr, iterator, callback)
如果集合里每一个元素都满足条件,则传给最终回调的result为true,否则为false
例1:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 1 );
}
async.every(arr, iterator, function (result) {
console.log( result ); // true
});
例2:
var arr = [2, 5, 9, 10];
function iterator (item, done) {
done( item > 5 );
}
async.every(arr, iterator, function (result) {
console.log( result ); // false
});
concat(arr, iterator, callback)
将多个异步操作的结果合并为一个数组。
语法:
concat(arr, iterator(item,callback(err, result)), callback(err, result))
code:
var arr = [
{
list : [1,2,3,4],
delay : 200
},{
list : [5,6,7],
delay : 100
},{
list : [8,9],
delay : 300
}
];
function iterator (item, done) {
console.log( ‘start:’, item.list )
setTimeout(function () {
console.log( ‘end:’, item.list )
done( null, item.list );
}, item.delay);
}
async.concat(arr, iterator, function (err, result) {
console.log( result ); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
});
结果为:
start: [ 1, 2, 3, 4 ]
start: [ 5, 6, 7 ]
start: [ 8, 9 ]
end: [ 5, 6, 7 ]
end: [ 1, 2, 3, 4 ]
end: [ 8, 9 ]
[ 5, 6, 7, 1, 2, 3, 4, 8, 9 ]
通过结果,会发现。这是一个并行的操作。合并之后的顺序是不固定的。
concatSeries(arr, iterator, callback)
与 concat 类似,不过 concatSeries 是串行的。
code:
var arr = [
{
list : [1,2,3,4],
delay : 200
},{
list : [5,6,7],
delay : 100
},{
list : [8,9],
delay : 300
}
];
function iterator (item, done) {
console.log( ‘start:’, item.list )
setTimeout(function () {
console.log( ‘end:’, item.list )
done( null, item.list );
}, item.delay);
}
async.concatSeries(arr, iterator, function (err, result) {
console.log( result ); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
});
结果是:
start: [ 1, 2, 3, 4 ]
end: [ 1, 2, 3, 4 ]
start: [ 5, 6, 7 ]
end: [ 5, 6, 7 ]
start: [ 8, 9 ]
end: [ 8, 9 ]
[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]Node.js Async Collections 介绍
async 是一个强大的工具模块,提供了多种异步操作的方法。本文主要介绍 async 模块中的集合操作方法。这些方法可以帮助我们在处理数组时更方便地进行并行或串行的异步操作。
each(arr, iterator, callback)
each 方法用于对数组中的每个元素执行一个异步操作,并且这些操作是并行执行的。
示例代码
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:' + item.name);
setTimeout(function() {
console.log('end: ' + item.name);
done(null);
}, item.delay);
}
async.each(arr, iterator, function(err) {
console.log('err: ' + err);
});
输出结果
start:a
start:b
start:c
end: b
end: a
end: c
err: undefined
eachSeries(arr, iterator, callback)
eachSeries 方法与 each 类似,但它是依次执行的。
示例代码
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:' + item.name);
setTimeout(function() {
console.log('end: ' + item.name);
done(null);
}, item.delay);
}
async.eachSeries(arr, iterator, function(err) {
console.log('err: ' + err);
});
输出结果
start:a
end: a
start:b
end: b
start:c
end: c
err: undefined
eachLimit(arr, limit, iterator, callback)
eachLimit 方法允许你限制并行执行的数量。
示例代码
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:' + item.name);
setTimeout(function() {
console.log('end: ' + item.name);
done(null);
}, item.delay);
}
async.eachLimit(arr, 1, iterator, function(err) {
console.log('err: ' + err);
});
输出结果
start:a
end: a
start:b
end: b
start:c
end: c
err: undefined
map(arr, iterator, callback)
map 方法用于对数组中的每个元素应用一个转换函数,并返回一个新数组。
示例代码
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:', item.name);
setTimeout(function() {
console.log('end:', item.name);
done(null, item.name += '!');
}, item.delay);
}
async.map(arr, iterator, function(err, result) {
console.log('err: ', err);
console.log('result:', result);
});
输出结果
start: a
start: b
start: c
end: b
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
以上介绍了 async 模块中的一些常用集合操作方法。通过这些方法,我们可以更高效地处理数组中的异步操作。
Node.js Async Collections 介绍
async 是一个强大的工具模块,提供了多种方法来处理异步操作。在本文中,我们将重点介绍 async 模块中的集合方法。
each(arr, iterator, callback)
each 方法用于并行遍历数组。每次迭代时,会调用 iterator 函数,并在完成后调用 callback。
示例代码:
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:' + item.name);
setTimeout(function() {
console.log('end: ' + item.name);
done(null);
}, item.delay);
}
async.each(arr, iterator, function(err) {
console.log('err: ' + err);
});
输出结果:
start:a
start:b
start:c
end: b
end: a
end: c
err: undefined
eachSeries(arr, iterator, callback)
eachSeries 与 each 类似,但它会按顺序依次执行。
示例代码:
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:' + item.name);
setTimeout(function() {
console.log('end: ' + item.name);
done(null);
}, item.delay);
}
async.eachSeries(arr, iterator, function(err) {
console.log('err: ' + err);
});
输出结果:
start:a
end: a
start:b
end: b
start:c
end: c
err: undefined
eachLimit(arr, limit, iterator, callback)
eachLimit 允许设置并行处理的最大数量。
示例代码:
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:' + item.name);
setTimeout(function() {
console.log('end: ' + item.name);
done(null);
}, item.delay);
}
async.eachLimit(arr, 2, iterator, function(err) {
console.log('err: ' + err);
});
输出结果:
start:a
start:b
end: b
start:c
end: a
end: c
err: undefined
map(arr, iterator, callback)
map 方法用于将数组中的每个元素通过 iterator 函数转换为新的数组。
示例代码:
const async = require('async');
var arr = [{ name: 'a', delay: 200 }, { name: 'b', delay: 100 }, { name: 'c', delay: 300 }];
function iterator(item, done) {
console.log('start:', item.name);
setTimeout(function() {
console.log('end:', item.name);
done(null, item.name + '!');
}, item.delay);
}
async.map(arr, iterator, function(err, result) {
console.log('err: ', err);
console.log('result:', result);
});
输出结果:
start: a
start: b
start: c
end: b
end: a
end: c
err: undefined
result: [ 'a!', 'b!', 'c!' ]
这些方法可以帮助你在处理异步操作时更有效地管理数组。希望这些示例代码能帮助你更好地理解和使用 async 模块中的集合方法。

