Async

Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript.

Build

  • Node.js : npm install async --save
  • yarn : yarn add async
  • bower : bower install async

METHODS

Collections

主要实现对集合的遍历,排序,过滤,查询等功能

Function Description
concat 对集合中的元素进行异步操作,将结果组成一个新的集合
detect 得到集合中满足条件的第一个数组
each 对集合中每个元素进行异步操作
every 集合中是否每个元素都满足条件,返回bool
groupBy 对集合中的每个元素进行异步操作,根据条件分组
map 对集合中的每个元素通过异步操作,得到一个新的集合
reduce 使用一个初始值同集合中每一个元素进行异步操作,最后得到一个唯一的结果
filter 对集合中元素使用异步操作进行筛选,得到符合条件的集合
reject 与filter相似,只是判断条件时正好相反,得到剩下的元素的集合
some 集合中是否有至少一个元素满足条件,返回bool
sortBy 对集合中的数据进行异步操作,再根据值从小到大排序
transform 对集合中的每个元素顺序进行异步操作,得到的值顺序传入到一个新的集合中

concat(coll,iteratee,callback)

1
2
3
4
5
6
async.concat([1, 2, 3, 4, 5], function (num, callback) {
num = num + 2;
callback(null, num);
}, function (err, result) {
console.log(result); //[ 3, 4, 5, 6, 7 ]
});

detect(coll,iteratee,callback)

1
2
3
4
5
async.detect([13, 44, 23], function (item, callback) {
callback(null, item > 37);
}, function (err, result) {
console.log(result); //44
});

each(coll,iteratee,callback)

1
2
3
4
5
6
7
8
let obj = [];
async.each([1, 2, 3], function (num, callback) {
num = num * 2;
obj.push(num)
callback(null);
}, function (err) {
console.log(obj); //[ 2, 4, 6 ]
});

every(coll,iteratee,callback)

1
2
3
4
5
async.every([1, 21, 23], function (item, callback) {
callback(null, item > 10);
}, function (err, result) {
console.log(result); // false
});

groupBy(coll,iteratee,callback)

1
2
3
4
5
async.groupBy([23, 13, 43], function (num, callback) {
callback(null, num>20)
}, function (err, result) {
console.log(result);
});

map(coll,iteratee,callback)

1
2
3
4
5
6
async.map([1, 3, 5], function (item, callback) {
let transformed = item + 1;
callback(null, transformed);
}, function (err, results) {
console.log(results); //[ 2, 4, 6 ]
});

reduce(coll,iteratee,callback)

1
2
3
4
5
async.reduce([1, 2, 3], 0, function (memo, item, callback) {
callback(null, memo + item);
}, function (err, result) {
console.log(result); //6
});

filter(coll,iteratee,callback)

1
2
3
4
5
async.filter([1, 5, 3, 7, 2], function (item, callback) {
callback(null, item > 3);
}, function (err, results) {
console.log(results);// [5, 7]
});

reject(coll,iteratee,callback)

1
2
3
4
5
async.reject([4, 7, 88, 11, 36], function (item, callback) {
callback(null, item > 11);
}, function (err, results) {
console.log(results); //[ 4, 7, 11 ]
});

some(coll,iteratee,callback)

1
2
3
4
5
async.some([1, 5, 9], function (item, callback) {
callback(null, item > 10);
}, function (err, result) {
console.log(result); //false
});

sortBy(coll,iteratee,callback)

1
2
3
4
5
async.sortBy([1, 3, 5, 2, 6], function (num, callback) {
callback(null, num);
}, function (err, result) {
console.log(result); //[ 1, 2, 3, 5, 6 ]
});

transform(coll,iteratee,callback)

1
2
3
4
5
6
7
8
9
10
11
12
13
async.transform([1, 2, 3], function (acc, item, index, callback) {
acc.push(item * 2);
callback(null, acc);
}, function (err, result) {
console.log(result); //[ 2, 4, 6 ]
});

async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) {
obj[key] = val * 2;
callback(null, obj);
}, function (err, result) {
console.log(result); //{ a: 2, b: 4, c: 6 }
})

Control Flow

Function Description
auto 自动确定运行顺序,每个函数可以选择依赖于其他函数的首先完成
compose 传递异步函数的组合函数,每个函数使用的参数来自下一个函数的值
forever 循环调用自身函数,直至callback(err)
parallel 并行执行集合中的函数,结果作为数组
race 对数组中的函数并行操作,任一函数发生错误或完成则执行回调,得到该函数的err或者result
retry 返回错误前重新调用函数,可以设置次数times和间隔时间interval
series 顺序执行集合中的函数,结果组成一个数组
times 重复调用函数,结果组成一个数组
waterfall 顺序运行集合中的函数,函数的结果作为参数传递给下一个函数

控制function流程

auto

根据需求确定运行function的最佳顺序。每个功能可以选择依赖于其他功能首先完成,一旦满足要求就会运行每一个功能。一旦callback(err),则不会向下执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
async.auto({
get_data: function (callback) {
console.log('in get_data');
callback(null, 'data', 'converted to array');
},
make_folder: function (callback) {
console.log('in make_folder');
callback(null, 'folder');
},
write_file: ['get_data', 'make_folder', function (results, callback) {
console.log('in write_file', JSON.stringify(results));
callback(null, 'filename');
}],
email_link: ['write_file', function (results, callback) {
console.log('in email_link', JSON.stringify(results));
callback(null, {'file': results.write_file, 'email': 'user@example.com'});
}]
}, function (err, results) {
console.log('err = ', err);
console.log('results = ', results);
});

async.autoInject({
get_data: function (callback) {
callback(null, 'data', 'converted to array');
},
make_folder: function (callback) {
callback(null, 'folder');
},
write_file: function (get_data, make_folder, callback) {
callback(null, 'filename');
},
email_link: function (write_file, callback) {
callback(null, {'file': write_file.write_file, 'email': 'user@example.com'});
}
}, function (err, results) {
console.log('err = ', err);
console.log('results = ', results);
});

compose

传递异步函数的组合函数,每个函数使用的参数来自下一个函数的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add1(n, callback) {
setTimeout(function () {
callback(null, n + 1);
}, 10);
}

function mul3(n, callback) {
setTimeout(function () {
callback(null, n * 3);
}, 10);
}

var add1mul3 = async.compose(mul3, add1);
add1mul3(4, function (err, result) {
console.log(result);
});

forever

使用回调参数调用函数,该参数允许函数无限调用自身,直到传入错误参数给回调,则循环停止

1
2
3
4
5
6
7
8
9
10
11
12
async.forever(
function (callback) {
console.log(count++);
if (count < 10)
cllback(null);
else
callback('End');
},
function (err) {
console.log(err);
}
);

parallel

同时执行集合中的函数,并将结果作为数组传递给callback

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async.parallel({
one: function (callback) {
setTimeout(function () {
callback(null, 1);
}, 200);
},
two: function (callback) {
setTimeout(function () {
callback(null, 2);
}, 100);
}
}, function (err, results) {
console.log(results);
});

race

对数组中的函数并行操作,任何一个函数完成则执行回调,得到该函数的err或者result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async.race([
function (callback) {
setTimeout(function () {
callback(null, 'one');
}, 200);
},
function (callback) {
setTimeout(function () {
callback(null, 'two');
}, 100);
}
], function (err, result) {
console.log(result);
});

retry

在返回错误前,重新调用该函数,可以设置重新调用的次数times和间隔时间interval

1
2
3
4
5
6
7
8
9
10
11
12
13
let count = 0
async.retry({times: 10, interval: 1000}, function (callback) {
console.log(count++);
if (count < 5)
callback('err');
else
callback(null, 'success');
}, function (err, result) {
if (err)
console.log(err);
else
console.log(result);
});

series

顺序执行集合中的函数,返回的结果组成一个新的数组,如果集合中任一函数callback(err),则不再向下执行函数

1
2
3
4
5
6
7
8
9
10
async.series([
function (callback) {
callback(null, 'one');
},
function (callback) {
callback(null, 'two');
}
], function (err, results) {
console.log(results);
});

times

重复运行函数,结果组成一个数组

1
2
3
4
5
6
7
let count = 0
async.times(5, function (n, callback) {
count++;
callback(null, count);
}, function (err, result) {
console.log(result); //[ 1, 2, 3, 4, 5 ]
});

waterfall

顺序运行集合中的函数,函数的结果传递个下一个函数,集合中任一函数callback(err),则不再向下运行

1
2
3
4
5
6
7
8
9
10
11
12
13
async.waterfall([
function (callback) {
callback(null, 'one', 'two');
},
function (arg1, arg2, callback) {
callback(null, 'three');
},
function (arg1, callback) {
callback(null, 'done');
}
], function (err, result) {
console.log(result);
});