Async 是一个实用程序模块,它为使用异步 JavaScript 提供了直接、 强大的函数。尽管最初设计用于与 Node.js 一起使用, 使用 npm install --save async
进行安装。 它也可以直接在浏览器中使用。
- Source:
- See:
Async 是一个实用程序模块,它为使用异步 JavaScript 提供了直接、 强大的函数。尽管最初设计用于与 Node.js 一起使用, 使用 npm install --save async
进行安装。 它也可以直接在浏览器中使用。
import concat from 'async/concat';
将 iteratee
应用到 coll
中的每一项, 连接的结果。 返回连接后的列表。 iteratee
s 被并行调用,结果在返回时被连接起来。不能保证结果数组以 coll
传递给 iteratee
函数的原始顺序返回。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback(err) |
function <optional> |
在所有的 |
async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) {
// files 现在是给定的 3 个目录中存在的文件名的一个列表(list)
});
import concatLimit from 'async/concatLimit';
与 concat
相同,但只能同时运行最多 limit
个的异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
在所有的 |
import concatSeries from 'async/concatSeries';
与 concat
相同,但每次只运行一个异步操作。「译者注:」也就说这个是按照传入顺序执行的,当然结果也就是顺序输出。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback(err) |
function <optional> |
在所有的 |
import detect from 'async/detect';
返回 coll
中的第一个通过 async 真实测试的值。iteratee
是并行应用的, 这意味着第一个返回 true
的迭代器将使用该结果触发探测(detect)callback
。 这意味着结果可能不是通过能够通过测试的最初的 coll
(按顺序)的第一个项目。 如果在原始的 coll
中顺序很重要,那么就看一下
detectSeries
。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
为 |
callback |
function <optional> |
当任意一个迭代器返回 |
async.detect(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, result) {
// 结果现在等于列表中的存在第一个文件
});
import detectLimit from 'async/detectLimit';
跟 detect
一样,但是只能同时运行最多 limit
个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
为 |
callback |
function <optional> |
当任意一个迭代器返回 |
import detectSeries from 'async/detectSeries';
与 detect
相同。但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
为 |
callback |
function <optional> |
当任意一个迭代器返回 |
import each from 'async/each';
将函数iteratee
并行地应用于 coll
中的每一个项目。
iteratee
被从列表中调用,当它完成时调用回调。 如果 iteratee
将一个错误传递给它的 callback
,则会立即使用错误对象调用主 callback
(针对 each
函数)。
注意,由于该函数将 iteratee
应用于每个项目,因此不能保证迭代器函数将按顺序完成。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用于 |
callback |
function <optional> |
一个当所有 |
// 假设 openFile 是一个文件名数组,saveFile 是一个用来保存文件的被修改内容的函数
async.each(openFiles, saveFile, function(err){
// 如果任何保存产生了错误, err 就等于那个错误
});
// 假设 openFile 是一个文件名数组
async.each(openFiles, function(file, callback) {
// 在这里执行文件上的操作。
console.log('Processing file ' + file);
if( file.length > 32 ) {
console.log('This file name is too long');
callback('File name too long');
} else {
// 在这里处理文件
console.log('File processed');
callback();
}
}, function(err) {
// 如果任何文件处理产生了错误, err 就等于那个错误
if( err ) {
// 其中一个迭代产生了一个错误。
// 所有的处理都将停止。
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
import eachLimit from 'async/eachLimit';
与 each
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
import eachOf from 'async/eachOf';
跟 each
一样,除了它将键(或索引)作为第二个参数传递给迭代器。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
var configs = {};
async.forEachOf(obj, function (value, key, callback) {
fs.readFile(__dirname + value, "utf8", function (err, data) {
if (err) return callback(err);
try {
configs[key] = JSON.parse(data);
} catch (e) {
return callback(e);
}
callback();
});
}, function (err) {
if (err) console.error(err.message);
// configs 现在是 JSON 数据的一个映射
doSomethingWith(configs);
});
import eachOfLimit from 'async/eachOfLimit';
与 eachOf
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个被应用于 |
callback |
function <optional> |
一个当所有 |
import eachOfSeries from 'async/eachOfSeries';
与 eachOf
一样,,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
import eachSeries from 'async/eachSeries';
与 each
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用于 |
callback |
function <optional> |
一个当所有 |
import every from 'async/every';
如果 coll
中的每个元素都满足异步测试,那么返回 true
。如果任何迭代器调用返回 false
,则会立即调用主 callback
。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个异步的真实测试,可以并行地应用到集合中的每一个项目。 结果为一个布尔值。 使用 (item, callback) 调用。 |
callback |
function <optional> |
一个当所有的 |
async.every(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, result) {
// 如果 result 为真,那么每个文件都存在
});
import everyLimit from 'async/everyLimit';
与 every
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个异步的真实测试,可以并行地应用到集合中的每一个项目。结果为一个布尔值。使用 (item, callback) 调用。 |
callback |
function <optional> |
一个当所有的 |
import everySeries from 'async/everySeries';
与 every
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个异步的真实测试,被应用于集合中的每一个项目。结果为一个布尔值。 使用 (item, callback) 调用。 |
callback |
function <optional> |
一个当所有的 |
import filter from 'async/filter';
返回一个由 coll
中通过异步真实测试的项目构成的新数组。这个操作是并行执行的,但是结果数组和原来的顺序是一样的。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
function |
一个真实测试,被应用于集合中的每一个项目。 |
callback |
function <optional> |
一个当所有的 |
async.filter(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, results) {
// results 现在等于存在的文件的数组
});
import filterLimit from 'async/filterLimit';
与 filter
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
function |
一个真实测试,被应用于集合中的每一个项目。 |
callback |
function <optional> |
一个当所有的 |
import filterSeries from 'async/filterSeries';
与 filter
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
function |
一个真实测试,被应用于集合中的每一个项目。 |
callback |
function <optional> |
一个当所有的 |
import groupBy from 'async/groupBy';
返回一个新对象,其中每个值对应于一个来自 coll
项目所构成的数组,并返回了对应的键。 也就是说,对象的键对应于传递给 iteratee
回调的值。
「译者注:」 本函数的作用是按照一定的规则对 coll
进行分组,每个分组为一个数组,数组与规则一一对应,并按照键值对的方式存储在一个对象中。
注意:由于该函数将 iteratee
并行地应用于每个项目,因此无法保证 iteratee
函数将按顺序完成。 但是, result
中的每个键的值的顺序将与原来的 coll
中的顺序相同。 对于对象,值将大致按照原始对象的键的顺序(但这可能在不同的 JavaScript 引擎中有所不同)。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) {
db.findById(userId, function(err, user) {
if (err) return callback(err);
return callback(null, user.age);
});
}, function(err, result) {
// result 是一个对象,它包含按照年龄分组的 usersIds。
// 例如 { 30: ['userId1', 'userId3'], 42: ['userId2']};
});
import groupByLimit from 'async/groupByLimit';
与 groupBy
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
import groupBySeries from 'async/groupBySeries';
与 groupBy
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
import map from 'async/map';
通过将 coll
中的每个值映射到 iteratee
函数,生成一个新的值集合。iteratee
使用来自 coll
的项目和一个对调函数进行调用,当它完成处理的时候,会调用这个回调。 每个回调都有两个参数:一个
error
,一个来自 coll
被转换过的项目。 如果 iteratee
将一个错误传递给它的回调,那么主 callback
(map函数的回调)会立即使用错误进行调用。
请注意,由于该函数将 iteratee
并行地应用于每个项目,因此无法保证 iteratee
函数将按顺序完成。然而,结果数组将与原来的 coll
的顺序相同。
如果 map
被传递给一个对象,结果将是一个数组。结果将大致按照原始对象的键顺序(但这可以在不同的JavaScript引擎中有所不同)。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
async.map(['file1','file2','file3'], fs.stat, function(err, results) {
// results 现在是每个文件的stats组成的数组。
});
import mapLimit from 'async/mapLimit';
与 map
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
import mapSeries from 'async/mapSeries';
与 map
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function <optional> |
一个当所有 |
import mapValues from 'async/mapValues';
与 map
相对应的,被设计用于对象。
通过将 obj
的每个值映射到 iteratee
函数,生成一个新对象。
iteratee
被 obj
的每个键值对和一个回调调用,当它完成处理时,这个回调会被调用。 每个回调都有两个参数:一个 error
,以及一个来自 obj
的经过转换的项。 如果 iteratee
将一个错误传递给它的回调,那么主 callback
(对于mapValues函数)会立即被错误调用。
注意,结果中的键的顺序得不到保证,这些键大致按照它们完成的顺序排列(但这是非常特定于引擎的)
Name | Type | Description |
---|---|---|
obj |
Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用于 |
callback |
function <optional> |
一个当所有 |
async.mapValues({
f1: 'file1',
f2: 'file2',
f3: 'file3'
}, function (file, key, callback) {
fs.stat(file, callback);
}, function(err, result) {
// result 现在是每个文件的 stats的一个映射。例如:
// {
// f1: [stats for file1],
// f2: [stats for file2],
// f3: [stats for file3]
// }
});
import mapValuesLimit from 'async/mapValuesLimit';
与 mapValues
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
obj |
Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个被应用于 |
callback |
function <optional> |
一个当所有 |
import mapValuesSeries from 'async/mapValuesSeries';
与 mapValues
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
obj |
Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用于 |
callback |
function <optional> |
一个当所有 |
import reduce from 'async/reduce';
使用一个异步 iteratee
将 coll
减少为单个值,以返回每一个连续的步骤。 memo
是reduction的初始状态。这个函数只连续地运行。
出于性能方面的原因,将此函数的调用拆分为一个并行映射,然后在结果上使用常规的 Array.prototype.reduce
可能是有意义的。 这个函数适用于 reduction 需要的每一步都是异步的情况;如果在减少数据之前可以获得数据,那么这样做可能是一个好主意。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
memo |
* |
reduction 的初始状态。 |
iteratee |
AsyncFunction |
一个应用于数组中的每一个项的函数,以生成 reduction 的下一个步骤。 一个应用于数组中的每一个项的函数,以生成 reduction 的下一个步骤的状态。 如果迭代器发生错误,reduction 就会停止,并且会使用错误立即调用 |
callback |
function <optional> |
一个当所有的 |
async.reduce([1,2,3], 0, function(memo, item, callback) {
// 毫无意义的异步:
process.nextTick(function() {
callback(null, memo + item)
});
}, function(err, result) {
// result 现在等于 memo 的最后的值,为6
});
import reduceRight from 'async/reduceRight';
与 reduce
一样,只对 array
进行逆序操作。
Name | Type | Description |
---|---|---|
array |
Array |
一个可以迭代的集合。 |
memo |
* |
reduction 的初始状态。 |
iteratee |
AsyncFunction |
一个应用于数组中的每一个项的函数,以生成 reduction 的下一个步骤。 一个应用于数组中的每一个项的函数,以生成 reduction 的下一个步骤的状态。如果迭代器发生错误,reduction 就会停止,并且会使用错误立即调用 |
callback |
function <optional> |
一个当所有的 |
import reject from 'async/reject';
与 filter
相反,移除通过 async
真实测试的值。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
function |
一个应用于每个 |
callback |
function <optional> |
一个当所有的 |
async.reject(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, results) {
// results 现在等于缺失文件的数组
createFiles(results);
});
import rejectLimit from 'async/rejectLimit';
与 reject
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
function |
一个应用于每个 |
callback |
function <optional> |
一个当所有的 |
import rejectSeries from 'async/rejectSeries';
与 reject
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
function |
一个应用于每个 |
callback |
function <optional> |
一个当所有的 |
import some from 'async/some';
如果在 coll
中至少有一个元素满足异步测试,那么返回 true
。 如果任何迭代器调用返回 true
,则会立即调用主 callback
。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被并行应用于每个 |
callback |
function <optional> |
一个当任意一个迭代器返回 |
async.some(['file1','file2','file3'], function(filePath, callback) {
fs.access(filePath, function(err) {
callback(null, !err)
});
}, function(err, result) {
// 如果 result 为 true,那么至少有一个文件是存在的
});
import someLimit from 'async/someLimit';
与 some
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
一个并行应用于每个 |
callback |
function <optional> |
一个当任意一个迭代器返回 |
import someSeries from 'async/someSeries';
与 some
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个并行应用于每个 |
callback |
function <optional> |
一个当任意一个迭代器返回 |
import sortBy from 'async/sortBy';
通过一个异步 iteratee
来运行每个 coll
值的结果来排序一个列表。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
iteratee |
AsyncFunction |
一个被应用到 |
callback |
function |
一个当所有的 |
async.sortBy(['file1','file2','file3'], function(file, callback) {
fs.stat(file, function(err, stats) {
callback(err, stats.mtime);
});
}, function(err, results) {
// results 现在是原始的文件数组经过使用修改后的数据进行排序的结果
});
// 通过修改回调参数,可以影响排序顺序:
// 升序排序
async.sortBy([1,9,3,5], function(x, callback) {
callback(null, x);
}, function(err,result) {
// result callback
});
// 降序排序
async.sortBy([1,9,3,5], function(x, callback) {
callback(null, x*-1); //<- x*-1 instead of x, turns the order around
}, function(err,result) {
// result callback
});
import transform from 'async/transform';
与 reduce
相关的。获取一个对象或数组,并对其每个元素进行连续的迭代,每一个步骤都可能会使一个 accumulator
的值发生变化。累加器的类型默认为传入的集合类型。
Name | Type | Description |
---|---|---|
coll |
Array | Iterable | Object |
一个可以迭代的集合。 |
accumulator |
* <optional> |
transform 的初始装套。如果省略了, 它默认为是一个空对象或数组,这取决于 |
iteratee |
AsyncFunction |
一个被应用于集合中可能修改累加器的每个项的函数。 |
callback |
function <optional> |
一个当所有的 |
async.transform([1,2,3], function(acc, item, index, callback) {
// 毫无意义的异步:
process.nextTick(function() {
acc.push(item * 2)
callback(null)
});
}, function(err, result) {
// result 现在等于 [2, 4, 6]
});
async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) {
setImmediate(function () {
obj[key] = val * 2;
callback();
})
}, function (err, result) {
// result 等于 {a: 2, b: 4, c: 6}
})
import applyEach from 'async/applyEach';
将所提供的参数应用于数组中的每个函数,在所有函数完成后调用 callback
。 如果您只提供第一个参数 fns
,那么它将返回一个函数,该函数允许您传入参数,就好像它是一个单独的函数调用。 如果提供了更多的参数,则必须要提供 callback
,而 args
仍然是可选的。
Name | Type | Description |
---|---|---|
fns |
Array | Iterable | Object |
一组具有相同调用参数的 AsyncFunction s。 |
args |
* <optional> |
传递给函数的任意数量的独立参数。 |
callback |
function <optional> |
当所有函数都完成处理时被调用的回调,它是 |
fns
,那么它将返回一个函数,该函数允许您传入参数,就好像它是一个单独的函数调用。 这个函数的签名为 (..args, callback)
。如果使用了任何参数调用该函数,必须指定callback
。async.applyEach([enableSearch, updateSchema], 'bucket', callback);
// 部分应用程序的例子:
async.each(
buckets,
async.applyEach([enableSearch, updateSchema]),
callback
);
import applyEachSeries from 'async/applyEachSeries';
与 applyEach
一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
fns |
Array | Iterable | Object |
一组具有相同调用参数的 AsyncFunction s。 |
args |
* <optional> |
传递给函数的任意数量的独立参数。 |
callback |
function <optional> |
当所有函数都完成处理时被调用的回调,它是 |
fns
,那么它将返回一个函数,该函数允许您传入参数,就好像它是一个单独的函数调用。import auto from 'async/auto';
根据它们的需求,确定在任务中运行 AsyncFunction s 的最佳顺序。 每个函数都可以选择依赖于先于它们自己完成的其他函数, 并且每个函数一旦需求得到满足都可以运行。
如果任何一个 AsyncFunction 将错误传递给回调, 那么
auto
序列就会停止。进一步的任务将不会执行(因此,任何依赖于它的其他函数都不会运行), 并且主 callback
会立即被错误调用。
AsyncFunction 还接收一个包含函数(到目前为止,fns
中已经执行完毕的函数)结果的对象,如果它们之间有依赖关系的话。如果任务函数之前没有依赖关系,那么只会传递一个回调给它。
Name | Type | Default | Description |
---|---|---|---|
tasks |
Object |
一个对象。它的每个属性都是一个函数或一个需求数组,而 AsyncFunction 本身就是数组中的最后一个项。 对象属性的键作为该属性定义的任务的名称,也就是说,在为其他任务指定需求时可以使用它。这个函数接收到一个或两个参数:
|
|
concurrency |
number <optional> | Infinity |
一个可选的 |
callback |
function <optional> |
一个可选的回调,当所有的任务都完成时,它会被调用。如果任何 |
undefined
async.auto({
// 这个函数将只会被传入一个回调
readData: async.apply(fs.readFile, 'data.txt', 'utf-8'),
showData: ['readData', function(results, cb) {
// results.readData 是文件的内容
// ...
}]
}, callback);
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));
// 一旦文件被写好,让我们发送一个连接给它。
// results.write_file 包含由 write_file 返回的文件名。
callback(null, {'file':results.write_file, 'email':'user@example.com'});
}]
}, function(err, results) {
console.log('err = ', err);
console.log('results = ', results);
});
import autoInject from 'async/autoInject';
一个依赖注入版本的 async.auto 函数。依赖任务被指定为函数的参数, 在通常的回调参数之后,参数名与所依赖的任务的名称匹配。这可以提供更易于阅读的任务图,更容易维护。
如果指定了最终回调,那么任务结果也会类似地注入,在初始错误参数之后指定为命名参数。
autoInject
函数是纯粹的语法糖,其语义与 async.auto 是等价的。
Name | Type | Description |
---|---|---|
tasks |
Object |
一个对象,其每个属性都是形如
|
callback |
function <optional> |
一个可选的回调,当所有的任务都执行完毕的时候被调用。 如果任意的一个 |
// `auto` 的例子可以被改写如下:
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) {
// 一旦文件写入完成,让我们发送一个链接给它...
// write_file 包含 write_file 返回的文件名。
callback(null, {'file':write_file, 'email':'user@example.com'});
}
}, function(err, results) {
console.log('err = ', err);
console.log('email_link = ', results.email_link);
});
// 如果你正在使用 JS 压缩器,它会对参数名进行管理
// `autoInject` 将不能与普通函数一起工作,因为参数名将会被折叠成一个单一的字母标识符。
// 为了解决这个问题,您可以显式地指定任务函数在数组中需要的参数名称,类似于 Angular.js 依赖注入。
// 这仍然比普通 `auto` 有优势,因为任务所依赖的结果(results)仍然会被扩展到参数中。
async.autoInject({
//...
write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
callback(null, 'filename');
}],
email_link: ['write_file', function(write_file, callback) {
callback(null, {'file':write_file, 'email':'user@example.com'});
}]
//...
}, function(err, results) {
console.log('err = ', err);
console.log('email_link = ', results.email_link);
});
import cargo from 'async/cargo';
使用指定的有效负载创建一个 cargo
对象。 添加到 cargo 的任务将被完全处理(达到 payload
限制)。 如果 worker
正在进行中,任务就会排队,直到它可用为止。 一旦 worker
完成了一些任务,就会调用这些任务的每个回调。 查看
这些 动画动画,了解
cargo
和 queue
是如何工作的。
当 queue
一次只将一个任务传递给一组 worker 时,cargo 会将一组任务传递给一个 worker,并在 worker 完成时重复。
Name | Type | Default | Description |
---|---|---|---|
worker |
AsyncFunction |
用于处理队列任务数组的异步函数。使用 |
|
payload |
number <optional> | Infinity |
一个可选的 |
一个用来管理任务的 cargo 对象。 回调可以作为特定的属性附加在 cargo 和内部队列的生命周期中监听特定的事件。
// 使用有效负载 2 创建一个 cargo 对象
var cargo = async.cargo(function(tasks, callback) {
for (var i=0; i<tasks.length; i++) {
console.log('hello ' + tasks[i].name);
}
callback();
}, 2);
// 添加一些项目
cargo.push({name: 'foo'}, function(err) {
console.log('finished processing foo');
});
cargo.push({name: 'bar'}, function(err) {
console.log('finished processing bar');
});
cargo.push({name: 'baz'}, function(err) {
console.log('finished processing baz');
});
import compose from 'async/compose';
创建一个函数,它是传入的的异步函数的组成部分。 每个函数都使用后面的函数的返回值。 组合函数 f()
, g()
, and h()
产生的结果是 f(g(h()))
,只有这个版本使用回调来获得返回值。
每一个函数都是通过组合后的函数的 this
绑定来执行的。
Name | Type | Description |
---|---|---|
functions |
AsyncFunction |
用于组合的异步函数 |
一个异步函数,它包含被组合的一组异步函数(functions
)。
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) {
// result 现在等于 15
});
import doDuring from 'async/doDuring';
during
的后检查(post check)版本。 为了反映操作顺序的不同,参数 test
和 fn
被交换了。
同时也是doWhilst
的带有异步 test
函数的版本。
Name | Type | Description |
---|---|---|
fn |
AsyncFunction |
一个每次 |
test |
AsyncFunction |
用于在每次执行 |
callback |
function <optional> |
在测试函数失败以及 |
import doUntil from 'async/doUntil';
Like 'doWhilst', except the test
is inverted. Note the argument ordering differs from until
.
Name | Type | Description |
---|---|---|
iteratee |
AsyncFunction |
一个每次 |
test |
function |
用来在每次 |
callback |
function <optional> |
一个在测试函数已经通过并且 |
import doWhilst from 'async/doWhilst';
whilst
的后检查(post-check)版本。 为了反映操作顺序的不同, test
和 iteratee
交换了位置。
doWhilst
跟 whilst
的关系,普通的 JavaScript 中 do while
与 while
一般。
Name | Type | Description |
---|---|---|
iteratee |
AsyncFunction |
每次 |
test |
function |
用来在每次 |
callback |
function <optional> |
一个在测试函数已经通过并且 |
import during from 'async/during';
像 whilst
一样, 除了 test
是一个异步函数,形如 function (err, truth)
的回调被传递给 test
函数。 如果错误被传递给 test
或者 fn
,主回调会立即使用错误的值被调用。
Name | Type | Description |
---|---|---|
test |
AsyncFunction |
用于在每次执行 |
fn |
AsyncFunction |
一个每次 |
callback |
function <optional> |
在测试函数失败以及 |
var count = 0;
async.during(
function (callback) {
return callback(null, count < 5);
},
function (callback) {
count++;
setTimeout(callback, 1000);
},
function (err) {
// 5 秒被传入
}
);
import forever from 'async/forever';
使用一个回调参数调用异步函数 fn
,该参数允许它连续地(in series),无限地调用自己。 如果将错误传递给回调,那么错误将调用 errback
,并且停止异步函数的执行,否则将永远不会调用它。
Name | Type | Description |
---|---|---|
fn |
AsyncFunction |
一个异步函数,可以反复调用。使用 (next)调用。 |
errback |
function <optional> |
当 |
async.forever(
function(next) {
// next 适用于传递信息,需要一个回调(callback(err [, whatever])
);
// 它将导致这个函数被再次调用。
},
function(err) {
// 如果使用一个在 next 的第一个参数的值调用 next,那么它会出现在这里作为 'err&apos;并且执行会停止。
}
);
import parallel from 'async/parallel';
并行地运行函数的 tasks
集合,而不等待上一个函数完成。 如果任意函数将错误传递给它们的回调,那么主 callback
就会立即被该错误的值调用。 一旦 tasks
完成,结果将作为数组传递给最终 callback
。
注意: parallel
是在并行地完成 I/O 任务,而不是并行地执行代码。 如果您的任务不使用任何计时器或执行任何 I/O,它们实际上将串行地(in series)执行。 每个任务的同步设置部分将会相继出现。 JavaScript 仍然是单线程的。
提示: 当一个任务失败时,使用 reflect
来继续其他任务的执行。
也可以使用对象而不是数组。每个属性将作为函数运行,运行的结果将作为对象(而不是数组)被传递给最终的callback
。 这可以是一种更可读的方法来处理 async.parallel 的结果。
Name | Type | Description |
---|---|---|
tasks |
Array | Iterable | Object |
一个用于执行的异步函数集合。 每个异步函数可以有任意数量的可选 |
callback |
function <optional> |
一个可选的回调,一旦所有的函数都成功完成,就可以运行了。 这个函数有一个 results 数组(或者 对象),它包含了传递给任务回调的所有 result 参数。 使用 (err, results) 调用。 |
async.parallel([
function(callback) {
setTimeout(function() {
callback(null, 'one');
}, 200);
},
function(callback) {
setTimeout(function() {
callback(null, 'two');
}, 100);
}
],
// 可选回调
function(err, results) {
// results 数组将等于 ['one','two']
// 尽管第二个函数有一个更短些的超时。
});
// 一个使用对象(而不是数组)的示例
async.parallel({
one: function(callback) {
setTimeout(function() {
callback(null, 1);
}, 200);
},
two: function(callback) {
setTimeout(function() {
callback(null, 2);
}, 100);
}
}, function(err, results) {
// results 现在等于: {one: 1, two: 2}
});
import parallelLimit from 'async/parallelLimit';
与 parallel
一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
tasks |
Array | Iterable | Object |
一个用于执行的 异步函数 集合。 每个异步函数可以有任意数量的可选 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
callback |
function <optional> |
一个可选的回调,一旦所有的函数都成功完成,就可以运行了。 这个函数有一个 results 数组(或者 对象),它包含了传递给任务回调的所有 result 参数。 使用 (err, results) 调用。 |
import priorityQueue from 'async/priorityQueue';
与 async.queue 一样,只有任务被指定优先级,并按照提升优先级顺序完成。
Name | Type | Description |
---|---|---|
worker |
AsyncFunction |
一个处理队列任务的异步函数。 如果你想处理来自个别任务的错误,传递一个回调到 |
concurrency |
number |
一个 |
一个用于管理任务的队列对象。queue
和 priorityQueue
对象有两个不同点
push(task, priority, [callback])
- priority
是一个数组。如果给定的是一个 tasks
数组,所有的任务将被指定相同的优先级。unshift
方法被移除了。import queue from 'async/queue';
使用指定的 concurrency
创建一个 queue
对象。 任务被添加到 queue
,并被并行地处理(知道达到 concurrency
的限制)。 如果所有的 worker
都正在进行,任务会排队等待,直到有一个可用。 一旦 worker
完成了一个 task
,这个
task
的回调就会被调用。
Name | Type | Default | Description |
---|---|---|---|
worker |
AsyncFunction |
一个处理队列任务的异步函数。 如果你想处理来自个别任务的错误,传递一个回调到 |
|
concurrency |
number <optional> | 1 |
一个 |
一个用于管理任务的队列对象。 回调可以作为特定的属性附加在队列的生命周期中监听特定的事件。
// 使用 concurrency 2 创建一个队列对象。
var q = async.queue(function(task, callback) {
console.log('hello ' + task.name);
callback();
}, 2);
// 指定一个回调
q.drain = function() {
console.log('all items have been processed');
};
// 添加一些项目到队列
q.push({name: 'foo'}, function(err) {
console.log('finished processing foo');
});
q.push({name: 'bar'}, function (err) {
console.log('finished processing bar');
});
// 添加一些项目到队列 (batch-wise 分批的)
q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
console.log('finished processing item');
});
// 添加一些项目到队首
q.unshift({name: 'bar'}, function (err) {
console.log('finished processing bar');
});
import race from 'async/race';
并行地运行 tasks
函数数组,不需要等待以前的函数完成。 一旦 tasks
中的任意一个任务完成或者传递了一个错误给它的回调,主 callback
就会被立即调用。 等效于 Promise.race()
。
Name | Type | Description |
---|---|---|
tasks |
Array |
一个用于执行的 异步函数 数组。 每个函数都可以有一个可选的 |
callback |
function |
一个回调,一旦任意一个任务函数完成就会运行。 这个函数会获得一个错误或者第一个执行完毕的函数的结果。 使用 (err, result) 调用。 |
undefined
async.race([
function(callback) {
setTimeout(function() {
callback(null, 'one');
}, 200);
},
function(callback) {
setTimeout(function() {
callback(null, 'two');
}, 100);
}
],
// 主回调
function(err, result) {
// 借过等于 'two',因为它完成得更早。
});
import retry from 'async/retry';
在返回错误之前,尝试从 task
中获得成功的响应的次数不超过 times
。 如果任务成功,则 callback
将被传入成功任务的结果。 如果所有尝试都失败了,那么回调将被传入最终尝试的错误和结果(如果有的话)。
Name | Type | Default | Description |
---|---|---|---|
opts |
Object | number <optional> | {times: 5, interval: 0}| 5 |
Can be either an object with
|
task |
AsyncFunction |
用于重试的异步函数。使用 (callback) 调用。 |
|
callback |
function <optional> |
一个可选的回调,当任务成功执行,或者最终的尝试失败的时候被调用。它接受完成 |
// The `retry` function can be used as a stand-alone control flow by passing
// 一个回调,如下所示:
// 尝试调用 apiMethod 3 次
async.retry(3, apiMethod, function(err, result) {
// 使用result 做点什么事儿
});
//尝试调用 apiMethod 3 次, 每次尝试间等待 200 ms
async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
// 使用result 做点什么事儿
});
// 使用指数后移调用 apiMethod 10次
// (即 intervals of 100, 200, 400, 800, 1600, ... 毫秒)
async.retry({
times: 10,
interval: function(retryCount) {
return 50 * Math.pow(2, retryCount);
}
}, apiMethod, function(err, result) {
// 使用result 做点什么事儿
});
// 使用默认的 0 间隔,5次 尝试调用 apiMethod。
async.retry(apiMethod, function(err, result) {
// 使用result 做点什么事儿
});
// 仅当错误条件满足时尝试调用 apiMethod,所有其他错误将中止重试控制流并返回到最终回调
async.retry({
errorFilter: function(err) {
return err.message === 'Temporary error'; // 仅当发生指定错误时继续重试。
}
}, apiMethod, function(err, result) {
// 使用result 做点什么事儿
});
// 要在其他控制流函数中重试不可靠的个别方法,请使用 `retryable` 包装器:
async.auto({
users: api.getUsers.bind(api),
payments: async.retryable(3, api.getPayments.bind(api))
}, function(err, results) {
// 使用result 做点什么事儿
});
import retryable from 'async/retryable';
与 retry
密切相关的。 这个方法将一个任务包装起来,并使它可以重试,而不是立即用重试的方式来调用它。
Name | Type | Default | Description |
---|---|---|---|
opts |
Object | number <optional> | {times: 5, interval: 0}| 5 |
可选选项, 与 |
task |
AsyncFunction |
用于包装的异步函数。这个函数将被传入返回的包装器。包装器函数可以接受任意的参数。 使用 (...args, callback) 调用。 |
包装后的函数,在错误时会基于指定的 opts
参数被调用进行重试。 这个函数将接受与 task
相同的参数。
async.auto({
dep1: async.retryable(3, getFromFlakyService),
process: ["dep1", async.retryable(3, function (results, cb) {
maybeProcessData(results.dep1, cb);
})]
}, callback);
import seq from 'async/seq';
compose
函数的阅读更自然的版本。 每个函数都使用前一个函数的返回值。 它等价于使用反转参数的 compose。「译者注:阅读体验更自然是因为,我们的阅读习惯现在是从左到右的,从上到下的,从前到后的。然而compose则相反。」
每个函数都使用组合后的 this
绑定来执行。
Name | Type | Description |
---|---|---|
functions |
AsyncFunction |
用来组合的一组异步函数。 |
一个函数,它是按照顺序组合的 functions
。
// 加载 lodash (或者 underscore), express3 和 dresende 的 orm2.
// 应用程序的一部分,这将获取已登录用户的cats。
// 这个示例使用 `seq` 函数来避免过度嵌套和错误。
// 处理混乱。
app.get('/cats', function(request, response) {
var User = request.models.User;
async.seq(
_.bind(User.get, User), // 'User.get' 有签名 (id, callback(err, data))
function(user, fn) {
user.getCats(fn); // 'getCats' 有签名 (callback(err, data))
}
)(req.session.user_id, function (err, cats) {
if (err) {
console.error(err);
response.json({ status: 'error', message: err.message });
} else {
response.json({ status: 'ok', message: 'Cats found', data: cats });
}
});
});
import series from 'async/series';
在 tasks
集合中连续地运行这个函数,每个运行一次,之前的函数都已经完成了。 如果 series 中的任何函数传递了一个错误给它的回调,那么不会有更多的函数被运行,并且 callback
会使用这个错误的值立即被调用。 否则,当 tasks
完成时, callback
会接收一个结果数组。
它也可以使用对象而不是数组。 任何一个属性将作为函数运行,运行的结果将会作为一个对象(而不是数组)被传递到最终的 callback
。 这可以是一种用来处理 async.series 的更可读的方式。
注意: 尽管许多实现保留了对象属性的顺序,ECMAScript 语言规范n 明确声明:
列举的这些属性的结构和顺序没有被指定。
因此,如果您依赖于执行一连串函数的顺序,并希望它在所有平台上工作,那么可以考虑使用数组。
Name | Type | Description |
---|---|---|
tasks |
Array | Iterable | Object |
一个用来串行运行的异步函数集合。 每个函数都可以有任意数量的可选 |
callback |
function <optional> |
一个可选的回调,一旦所有的函数都完成了就运行。 这个函数会得到一个 results 数组(或者对象),它包含了被传递到 所有 |
async.series([
function(callback) {
// 做一些事情 ...
callback(null, 'one');
},
function(callback) {
// 做更多事情...
callback(null, 'two');
}
],
// 可选的回调
function(err, results) {
// results 现在等于 ['one', 'two']
});
async.series({
one: function(callback) {
setTimeout(function() {
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function() {
callback(null, 2);
}, 100);
}
}, function(err, results) {
// results 现在等于: {one: 1, two: 2}
});
import times from 'async/times';
调用 iteratee
函数 n
次, 并以与 map 相同的方式积累结果。
Name | Type | Description |
---|---|---|
n |
number |
运行该函数的次数。 |
iteratee |
AsyncFunction |
那个应该被调用 |
callback |
function |
参见 map. |
// Pretend this is some complicated async factory
var createUser = function(id, callback) {
callback(null, {
id: 'user' + id
});
};
// 生成 5 个用户
async.times(5, function(n, next) {
createUser(n, function(err, user) {
next(err, user);
});
}, function(err, users) {
// 我们现在应该有 5 个user
});
import timesLimit from 'async/timesLimit';
与 times一样,但是只能同时运行最多 limit 个异步操作。
Name | Type | Description |
---|---|---|
count |
number |
运行该函数的次数。 |
limit |
number |
同时可以运行的异步操作的最大数量。 |
iteratee |
AsyncFunction |
那个应该被调用 |
callback |
function |
参见 async.map. |
import timesSeries from 'async/timesSeries';
与 times 一样,但同时只能运行一个异步操作。
Name | Type | Description |
---|---|---|
n |
number |
运行该函数的次数。 |
iteratee |
AsyncFunction |
那个应该被调用 |
callback |
function |
see map. |
import tryEach from 'async/tryEach';
它以串行的方式运行每一个任务,但是当任何函数成功时就会停止。 如果其中一个任务成功,则 callback
将被传入成功任务的结果。 如果所有的任务都失败了,那么回调将会被传入最终尝试的错误和结果(如果有的话)。
Name | Type | Description |
---|---|---|
tasks |
Array | Iterable | Object |
一个包含运行的所有函数的集合, 每个函数都被传入一个 |
callback |
function <optional> |
一个可选的回调,当所有任务的中的其中一个成功完成或者所有的任务都失败时被调用。 它接受 |
async.tryEach([
function getDataFromFirstWebsite(callback) {
// 尝试从第一个网站获取数据
callback(err, data);
},
function getDataFromSecondWebsite(callback) {
// 从第一个网站获取数据失败,
// 尝试从备用网站获取数据
callback(err, data);
}
],
// 可选的回调
function(err, results) {
// 现在使用获取的数据做点事情
});
import until from 'async/until';
重复地调用 iteratee
直到 test
返回 true
。如果任何迭代器调用返回。 当停止或者发生错误时调用 callback
。
callback
将被传入一个错误以及任何传递给最终的 iteratee
的回调的参数。
与 whilst相反。
Name | Type | Description |
---|---|---|
test |
function |
用于在每次执行 |
iteratee |
AsyncFunction |
每次 |
callback |
function <optional> |
一个在测试函数已经通过并且 |
import waterfall from 'async/waterfall';
连续地运行 tasks
函数数组, 每一个都将结果传递给数组中的下一个。 但是,如果任意一个 tasks
将错误传递给自己的回调,则不会执行下一个函数,并且会立即调用主callback
。
Name | Type | Description |
---|---|---|
tasks |
Array |
一个用来执行的 异步函数 数组。 每个函数都可以有任意数量的 |
callback |
function <optional> |
一个可选的回调,一旦所有的函数都完成了就运行。 最后一个任务的回调的 results 将给它。使用 (err, [results]) 调用。 |
undefined
async.waterfall([
function(callback) {
callback(null, 'one', 'two');
},
function(arg1, arg2, callback) {
// arg1 现在等于 'one' , arg2 现在等于 'two'
callback(null, 'three');
},
function(arg1, callback) {
// arg1 现在等于 'three'
callback(null, 'done');
}
], function (err, result) {
// result 现在等于 'done'
});
// 或者, 使用命名函数:
async.waterfall([
myFirstFunction,
mySecondFunction,
myLastFunction,
], function (err, result) {
// result 现在等于 'done'
});
function myFirstFunction(callback) {
callback(null, 'one', 'two');
}
function mySecondFunction(arg1, arg2, callback) {
// arg1 现在等于 'one' , arg2 现在等于 'two'
callback(null, 'three');
}
function myLastFunction(arg1, callback) {
// arg1 现在等于 'three'
callback(null, 'done');
}
import whilst from 'async/whilst';
如果 test
返回 true
,那么就反复调用 iteratee
。 当停止时或者发生错误时调用 callback
。
Name | Type | Description |
---|---|---|
test |
function |
用于在每次执行 |
iteratee |
AsyncFunction |
每次 |
callback |
function <optional> |
一个在测试函数失败以及被反复执行的 |
undefined
var count = 0;
async.whilst(
function() { return count < 5; },
function(callback) {
count++;
setTimeout(function() {
callback(null, count);
}, 1000);
},
function (err, n) {
// 5 seconds 被传入, n = 5
}
);
import cargo from 'async/cargo';
任务中的一个 cargo,用于被 worker 函数完成。 cargo 继承了所有与 queue
相同的方法和事件回调>。
Name | Type | Description |
---|---|---|
length |
function |
一个函数,用来返回等待处理的条目的数量的。 像 |
payload |
number |
一个 |
push |
function |
添加 |
saturated |
function |
当 |
empty |
function |
一个回调,当 |
drain |
function |
当 |
idle |
function |
一个函数,如果存在等待或处理的项,则返回false;如果不是,则返回 true。 像 |
pause |
function |
一个函数,它可以暂停处理任务,直到 |
resume |
function |
一个函数,它可以恢复处理被暂停的任务队列,像 |
kill |
function |
一个函数,它可以移除 |
import queue from 'async/queue';
一个用于被 worker 函数完成的任务队列。
Name | Type | Description |
---|---|---|
length |
function |
一个函数,用于返回等待被处理的项目的数量。像 |
started |
boolean |
一个布尔值,用以指示是否有任何项目被队列所推入和处理。 |
running |
function |
一个函数,用以返回正在被处理的项目的数量。像 |
workersList |
function |
一个函数,返回当前正在被处理的项目的数组。像 |
idle |
function |
一个函数,用以指示当前队列是否处理空闲状态。有项目在等待或者正在被处理,则返回false,如果为空,则返回 true。 这样调用: |
concurrency |
number |
一个整数,用于确定 并行运行的 |
push |
function |
添加一个新任务到 |
unshift |
function |
添加一个新的任务到 |
remove |
function |
从队列中移除与 test 函数匹配的项目。 test 函数将获得一个对象,如果这是一个 priorityQueue 对象,那么该对象有一个 |
saturated |
function |
一个回调,当运行的 worker 数量超过 |
unsaturated |
function |
一个回调,当运行的 worker 数量小于 |
buffer |
number |
一个最小阈值缓冲区,用于表示 |
empty |
function |
一个回调,当 |
drain |
function |
当 |
error |
function |
一个回调,当任务出现错误时被调用。有签名如: |
paused |
boolean |
一个布尔值,用于确定队列是否处于暂停状态。 |
pause |
function |
一个函数,它可以暂停处理任务,直到 |
resume |
function |
一个函数,它可以恢复被暂停处理的队列。 像这样调用 |
kill |
function |
一个函数,用以移除 |
import apply from 'async/apply';
使用一些已经应用的参数创建一个接续函数(continuation function)。
当与其他控制流函数结合时,作为简写很有帮助。 传递给返回的函数的任何参数都被添加到最初的函数(传递给 apply的)的参数中。「译者注:也就上面的fn
。」
「译者注:这里的接续函数是指,使用apply 包裹 fn 后创建的函数可以接收任意数量的参数,并且该函数会挨个对这些参数进行处理。」
Name | Type | Description |
---|---|---|
fn |
function |
你想要最终应用所有参数的函数。使用 (arguments...) 调用。 |
arguments... |
* |
当接续函数被调用时,会自动应用任何数量的参数。 |
局部应用(partially-applied)的函数
// 使用 apply
async.parallel([
async.apply(fs.writeFile, 'testfile1', 'test1'),
async.apply(fs.writeFile, 'testfile2', 'test2')
]);
// 与不使用 apply 的相同过程
async.parallel([
function(callback) {
fs.writeFile('testfile1', 'test1', callback);
},
function(callback) {
fs.writeFile('testfile2', 'test2', callback);
}
]);
// 当调用 continuation 时,它可以被传入任意数量的附加参数:
node> var fn = async.apply(sys.puts, 'one');
node> fn('two', 'three');
one
two
three
import asyncify from 'async/asyncify';
使用一个同步函数并使其为异步化,将其返回值传递给一个回调函数。 这对于将同步函数插入瀑布(waterfall)、序列(series)或其他异步函数非常有用。 传递给生成的函数的任何参数都将被传递给包裹函数(除了参数中处于最后的回调
f(args..., callback)
)。 抛出的错误将被传递给回调。
如果传递给 asyncify
的函数返回一个 Promise,那么这个承诺的 resolved/rejected 状态将被用于调用回调,而不是简单的同步返回值。
这也意味着您可以将 ES2017 async
函数异步化。
Name | Type | Description |
---|---|---|
func |
function |
同步函数,或者返回 Promise 的函数。用于被转换成一个 AsyncFunction . |
func
的一个异步包装器。 使用 (args..., callback)
调用。
// 传递一个常规的同步函数
async.waterfall([
async.apply(fs.readFile, filename, "utf8"),
async.asyncify(JSON.parse),
function (data, next) {
// 数据是解析文本的结果。
// 如果解析发生错误,这个错误会被捕获。
}
], callback);
// 传入一个返回 Promise 的函数
async.waterfall([
async.apply(fs.readFile, filename, "utf8"),
async.asyncify(function (contents) {
return db.model.create(contents);
}),
function (model, next) {
// `model` 是实例化的 model 对象。
// 如果有一个错误,这个函数就会被跳过。
}
], callback);
// es2017 示例, 如果你的 JS 环境支持开箱即用的 async 函数, 那么不需要 `asyncify`
var q = async.queue(async.asyncify(async function(file) {
var intermediateStep = await processFile(file);
return await somePromise(intermediateStep)
}));
q.push(files);
import constant from 'async/constant';
当它被调用时,返回一个函数,使用提供的值进行调用-返回。 对于作为 waterfall
的第一个函数,或者将值插入 auto
中很有帮助。
Name | Type | Description |
---|---|---|
arguments... |
* |
任意数量的参数都将自动调用回调。 |
当被调用时返回一个函数,使用之前给定的参数自动调用调用回调。
async.waterfall([
async.constant(42),
function (value, next) {
// value === 42
},
//...
], callback);
async.waterfall([
async.constant(filename, "utf8"),
fs.readFile,
function (fileData, next) {
//...
}
//...
], callback);
async.auto({
hostname: async.constant("https://server.net/"),
port: findFreePort,
launchServer: ["hostname", "port", function (options, cb) {
startServer(options, cb);
}],
//...
}, callback);
import dir from 'async/dir';
记录一个异步
函数 的结果到
控制台
使用 console.dir
来显示结果对象的属性。 仅在 Node.js 或者支持 console.dir
和
console.error
(例如 FF and Chrome) 的浏览器中工作。如果从异步函数返回多个参数,
console.dir
会按照顺序调用每一个参数。
Name | Type | Description |
---|---|---|
function |
AsyncFunction |
您希望最终应用所有参数的函数。 |
arguments... |
* |
应用于函数的任意数量的参数。 |
// 在一个模块中
var hello = function(name, callback) {
setTimeout(function() {
callback(null, {hello: name});
}, 1000);
};
// 在 node 控制台中
node> async.dir(hello, 'world');
{hello: 'world'}
import ensureAsync from 'async/ensureAsync';
包裹一个异步函数,并确保它在事件循环的后一轮调用它的回调。 如果函数已经在下一轮(tick)调用了它的回调,没有额外的延迟。 这常被用来防止堆栈溢出 (
RangeError: Maximum call stack size exceeded
) 和 并且通常保持Zalgo的控制是很有用的。 ES2017 async
函数是按原样返回的 -- 他们的对 Zalgo的腐化免疫,因为他们总是在后一轮里解决(resolve)。
Name | Type | Description |
---|---|---|
fn |
AsyncFunction |
一个异步函数,它期望 node样式的回调作为它的最后一个参数。 |
返回一个包裹函数,它与传入的函数具有完全相同的调用签名。
function sometimesAsync(arg, callback) {
if (cache[arg]) {
return callback(null, cache[arg]); // 这将是同步的!!
} else {
doSomeIO(arg, callback); // 这个 IO 将是异步的。
}
}
// 如果将许多结果缓存在行中,则会出现堆栈溢出的风险
async.mapSeries(args, sometimesAsync, done);
// 如果有必要,这将推迟 sometimesAsync 的回调,
// 防止堆栈溢出
async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
import log from 'async/log';
记录一个 async
函数的结果到 控制台
。 仅在 Node.js 或者支持 console.dir 和 console.error (例如 FF and Chrome) 的浏览器中工作。 如果从异步函数返回多个参数, console.log
会按照顺序调用每一个参数。
Name | Type | Description |
---|---|---|
function |
AsyncFunction |
您希望最终应用所有参数的函数。 |
arguments... |
* |
应用于函数的任意数量的参数。 |
// 在一个模块中
var hello = function(name, callback) {
setTimeout(function() {
callback(null, 'hello ' + name);
}, 1000);
};
// 在 node 控制台
node> async.log(hello, 'world');
'hello world'
import memoize from 'async/memoize';
缓存一个异步函数的结果。当创建一个哈希来存储函数结果时,从哈希中省略了回调,并且可以使用一个可选的哈希函数。
如果没有指定哈希函数,那么第一个参数将被用作哈希键,如果它是一个字符串或数据类型则转换为一个不同的字符串,那么它可能会正常工作。 注意,对象和数组不会有合理的行为。 其他参数是有效的也不行。在这种情况下,指定您自己的哈希函数。
结果的缓存是由 memoize
返回的函数的 memo
属性暴露的。
Name | Type | Description |
---|---|---|
fn |
AsyncFunction |
用于代理和缓存结果的异步函数。 |
hasher |
function |
一个可选函数,用于为存储结果生成一个自定义的哈希。除了回调,它还有所有应用于它的参数。 必须是同步的。 |
fn
的缓存版本(memoized)
var slow_fn = function(name, callback) {
// do something
callback(null, result);
};
var fn = async.memoize(slow_fn);
// fn 现在可以被用作 slow_fn了
fn('some name', function() {
// callback
});
import nextTick from 'async/nextTick';
在事件循环的下一个循环调用 callback
。 在 Node.js 中,这只需要调用 process.nextTick
。 在浏览器中,如果 setImmediate
可用,使用它。 否则使用 setTimeout(callback, 0)
, 这意味着其他更高优先级的事件可能会在 callback
执行之前执行。
这在内部是用于浏览器兼容性的。
Name | Type | Description |
---|---|---|
callback |
function |
该函数在事件循环的后面的循环中被调用。使用 (args...) 调用。 |
args... |
* |
在下一轮循环中传递给回调的任何数量的附加参数。 |
var call_order = [];
async.nextTick(function() {
call_order.push('two');
// call_order 现在等于 ['one','two']
});
call_order.push('one');
async.setImmediate(function (a, b, c) {
// a, b, 和 c 等于 1, 2, 和 3
}, 1, 2, 3);
import reflect from 'async/reflect';
将异步函数包装在另一个函数中,该函数的结果是一个对象,即使在它出错时也是如此。
该结果对象可以是有属性 error
或者 value
.
Name | Type | Description |
---|---|---|
fn |
AsyncFunction |
你想包裹的异步函数。 |
object
,这个对象有一个 error
或者一个 value
属性。async.parallel([
async.reflect(function(callback) {
// do some stuff ...
callback(null, 'one');
}),
async.reflect(function(callback) {
// do some more stuff but error ...
callback('bad stuff happened');
}),
async.reflect(function(callback) {
// do some more stuff ...
callback(null, 'two');
})
],
// optional callback
function(err, results) {
// values
// results[0].value = 'one'
// results[1].error = 'bad stuff happened'
// results[2].value = 'two'
});
import reflectAll from 'async/reflectAll';
一个使用 reflect
来包裹函数数组或对象的助手函数。
Name | Type | Description |
---|---|---|
tasks |
Array | Object | Iterable |
包裹进 |
返回一个异步函数数组,每个函数都被包裹进 async.reflect
let tasks = [
function(callback) {
setTimeout(function() {
callback(null, 'one');
}, 200);
},
function(callback) {
// do some more stuff but error ...
callback(new Error('bad stuff happened'));
},
function(callback) {
setTimeout(function() {
callback(null, 'two');
}, 100);
}
];
async.parallel(async.reflectAll(tasks),
// optional callback
function(err, results) {
// values
// results[0].value = 'one'
// results[1].error = Error('bad stuff happened')
// results[2].value = 'two'
});
// 使用对象的示例
let tasks = {
one: function(callback) {
setTimeout(function() {
callback(null, 'one');
}, 200);
},
two: function(callback) {
callback('two');
},
three: function(callback) {
setTimeout(function() {
callback(null, 'three');
}, 100);
}
};
async.parallel(async.reflectAll(tasks),
// optional callback
function(err, results) {
// values
// results.one.value = 'one'
// results.two.error = 'two'
// results.three.value = 'three'
});
import setImmediate from 'async/setImmediate';
在事件循环的之后的循环调用 callback
。在 Node.js 中,只需要调用 setImmediate
。在浏览器中,如果 setImmediate
可用就使用它。否则,使用 setTimeout(callback, 0)
, which means other higher priority events may precede the execution
of callback
.
这在内部是用于浏览器兼容性的。
Name | Type | Description |
---|---|---|
callback |
function |
该函数在事件循环的后面的循环中被调用。使用 (args...) 调用。 |
args... |
* |
在下一轮循环中传递给回调的任何数量的附加参数。 |
var call_order = [];
async.nextTick(function() {
call_order.push('two');
// call_order 现在等于 ['one','two']
});
call_order.push('one');
async.setImmediate(function (a, b, c) {
// a, b, 和 c 等于 1, 2, 和 3
}, 1, 2, 3);
import timeout from 'async/timeout';
设置异步函数的时间限制。如果函数在指定的时间内未调用回调,那么它将使用一个超时错误调用回调。 错误对象的代码属性将是 'ETIMEDOUT'
。
Name | Type | Description |
---|---|---|
asyncFn |
AsyncFunction |
收到事件限制的异步函数。 |
milliseconds |
number |
指定的时间限制。 |
info |
* <optional> |
任何想要附加的超时错误对象 Error的变量( |
返回一个包裹函数,可以和任何控制流函数配合使用。就像使用 asyncFunc
的那样,使用与之相同的参数调用这个函数。
function myFunction(foo, callback) {
doAsyncTask(foo, function(err, data) {
// 处理 errors
if (err) return callback(err);
// do some stuff ...
// 返回处理后的 data
return callback(null, data);
});
}
var wrapped = async.timeout(myFunction, 1000);
// 就像调用 `myFunction` 那样调用 `wrapped`
wrapped({ bar: 'bar' }, function(err, data) {
// 如果 `myFunction` 花费 < 1000 ms的事件来执行,`err`
// `err` 和 `data` 将包含他们执行后的值
// 否则 `err` 将是一个 Error,错误代码为 'ETIMEDOUT'
});
import unmemoize from 'async/unmemoize';
撤销函数的 memoize 操作, 恢复为原始的,未缓存的形状。 方便测试。
Name | Type | Description |
---|---|---|
fn |
AsyncFunction |
缓存化(memoized)的函数 |
返回一个函数,这个函数调用原始的未缓存化的函数。