Collections (集合)
1. each
each - 对同一个集合之中的所有元素都执行同一个异步操作
Template 1
async.each([0,1,2,3,4,5,6,7,8,9], function(item, callback) {
setTimeout(function() {
console.log('>', item);
callback();
}, 2 * Math.random() * 1000);
}, function(err) {
console.log('> done');
});
console.log(':)');
Output 1
:)
> 4
> 5
> 2
> 7
> 8
> 3
> 0
> 1
> 9
> 6
> done
Template 2
async.each([0,1,2,3,4,5,6,7,8,9], function(item, callback) {
setTimeout(function() {
console.log('>', item);
if (item === 3) {
callback("error: This item eque 3");
}
else {
callback();
}
}, 2 * Math.random() * 1000);
}, function(err) {
if (err) {
console.log('some error');
console.log(err);
}
else {
console.log('success');
}
console.log('> done');
});
console.log(':)');
Output 2
:)
> 9
> 2
> 8
> 0
> 4
> 5
> 3
some error
error: This item eque 3
> done
> 1
> 6
> 7
综合如上的两个例子,可得出在分别处理集合元素的过程中,传入callback()的信息会当作error经由回调用函数处理,不传递参数的callback()则视为执行成功,如果集合中没有没有任何错误,那么最终会调用一次回调函数,比如Template 1
中输出> done
还有一个地方值的一说
上图所示为官方的文档,网址:https://github.com/caolan/async
关于集合的操作方法中大多都分为两种,比如之前介绍的each,可以分为eachSeries和eachLimit两种
Template 3
async.each([0,1,2,3,4,5,6,7,8,9], function(item, callback) {
if (item === 3) {
setTimeout(function () {
console.log('>', item);
callback();
}, 1000);
}
else {
console.log('>', item);
callback();
}
}, function(err) {
console.log('> done');
});
console.log(':)');
Output 3
> 0
> 1
> 2
> 4
> 5
> 6
> 7
> 8
> 9
:)
> 3
> done
Template 4
async.eachSeries([0,1,2,3,4,5,6,7,8,9], function(item, callback) {
if (item === 3) {
setTimeout(function () {
console.log('>', item);
callback();
}, 1000);
}
else {
console.log('>', item);
callback();
}
}, function(err) {
console.log('> done');
});
console.log(':)');
Output 4
> 0
:)
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> done
Template 5
async.eachLimit([0,1,2,3,4,5,6,7,8,9], 1, function(item, callback) {
if (item === 3) {
setTimeout(function () {
console.log('>', item);
callback();
}, 1000);
}
else {
console.log('>', item);
callback();
}
}, function(err) {
console.log('> done');
});
console.log(':)');
Output 5
> 0
> 1
> 2
:)
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> done
Template 6
async.eachLimit([0,1,2,3,4,5,6,7,8,9], 3, function(item, callback) {
if (item === 3) {
setTimeout(function () {
console.log('>', item);
callback();
}, 1000);
}
else {
console.log('>', item);
callback();
}
}, function(err) {
console.log('> done');
});
console.log(':)');
Output 6
> 0
> 1
> 2
> 4
> 5
> 6
> 7
> 8
> 9
:)
> 3
> done
上边共四个例子,一个是each,一个是eachSeries,另外两个是eachLimit不同参数的
结果可知,each为异步执行的,eachSeries为同步执行的,可以保证执行顺序与列表顺序相应,当eachLimit设置限制为1时表现与eachSeries相同,不为1时则与each相同
可能那个笑脸大家也注意到了,位置出现的不同,我解释不了,只能说可能是因为不同函数的实现导致,想把这个笑脸最后输出,按照代码的顺序,就需要其它控制函数
还有一个很重要的注意事项,同步执行的情况下,如果出现错误则会终止,并执行回调函数,异步情况下则不受影响
2. forEachOf
forEachOf - 对同一个集合之中的所有元素都执行同一个异步操作,类似于each,可以传递key与value两个值
Template 7
var obj = {one: '1', two: '2', three: '3'};
async.forEachOf(obj, function (value, key, callback) {
console.log(key, value);
callback();
}, function (err) {
if (err) console.log(err);
console.log("> done");
})
Output 7
one 1
two 2
three 3
> done
forEachOf也是有两种相关函数,forEachOfSeries与forEachOfLimit,类比于each,此处以及以后不再提及
3. map
map - 提供一个新的数组来存储处理后的结果,它的callback的函数第一个参数接收error,第二个参数用来返回处理后的值
Template 8
async.map([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], function (item, callback) {
if (item === 3) {
setTimeout(function () {
callback(null, item + 10)
}, 1000);
}
else {
callback(null, item + 10)
}
}, function (err, result) {
console.log(result);
});
Output 8
[ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ]
文档中提及,函数不保证每个元素按照顺序处理完成,但是可以保证新生成的顺序顺序与原数组保持一致
4. filter
filter - 过滤数组中的元素,iterator的回调中只接受true或false
Template 9
async.filter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], function (item, callback) {
if (item % 2 === 0) {
callback(true);
}
else {
callback(false);
}
}, function (results) {
console.log(results);
})
Output 9
[ 0, 2, 4, 6, 8 ]
5. reject
reject - 与filter的作用正好相反,剔除通过验证的值
6. sortBy
sortBy - 排序,回调中返回排序后的数组
Template 10
// 正序排序
async.sortBy([1,9,3,5], function(x, callback){
callback(null, x);
}, function(err,result){
console.log(result);
});
// 逆序排序
async.sortBy([1,9,3,5], function(x, callback){
callback(null, x*-1);
}, function(err,result){
console.log(result);
});
Output 10
[ 1, 3, 5, 9 ]
[ 9, 5, 3, 1 ]
7. some/any
some - 如果存在执行成功的则result为true,否则为false
async.some(['file1','file2','file3'], fs.exists, function(result){
// if result is true then at least one of the files exists
});
8. every/all
every - 如果所有都执行成功则result为true,否则为false
async.every(['file1','file2','file3'], fs.exists, function(result){
// if result is true then every file exists
});
集合部分我觉得常用的就这么些了,async在处理数组方面真是挺不错的。