neo-async 模块
Posted 前端精髓
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了neo-async 模块相关的知识,希望对你有一定的参考价值。
neo-async 和 async 模块都是为了解决嵌套金字塔,和异步流程控制而生,neo-async 是 async 的替代品,因为 neo-async 比 async 的性能更快。
为什么要使用这个模块,举个例子,比如我们需要读取多个文件,将读取文件的结果保存在数组中。
let list = []
fs.readFile('file1', 'utf8', function (err, res)
list.push(res)
fs.readFile('file2', 'utf8', function (err, res)
list.push(res)
fs.readFile('file3', 'utf8', function (err, res)
list.push(res)
console.log(res)
)
)
)
使用 neo-async 我们可以这样写:
function getFile(file, callback)
fs.readFile(file, 'utf8', function (err, res)
if (err)
return callback(err);
callback(null, res);
);
async.map(['file1','file2','file3'], getFile, function(err, results)
// 返回一个新数组
console.log(res)
);
each
注意,由于此函数并行地将 iterator 应用于每个项,因此不能保证 iterator 函数将按顺序完成。
// array
var order = [];
var array = [1, 3, 2];
var iterator = function(num, done)
setTimeout(function()
order.push(num);
done();
, num * 10);
;
async.each(array, iterator, function(err, res)
console.log(res); // undefined
console.log(order); // [1, 2, 3]
);
与 each 相同,但一次最多运行多少异步操作,可以自己设置限制。
eachLimit
// array
var order = [];
var array = [1, 5, 3, 4, 2];
var iterator = function(num, done)
setTimeout(function()
order.push(num);
done();
, num * 10);
;
async.eachLimit(array, 2, iterator, function(err, res)
console.log(res); // undefined
console.log(order); // [1, 3, 5, 2, 4]
);
控制并发数量的实现原理如下:
var noop = function noop() ;
function timesSync(n, iterator)
var index = -1;
while (++index < n)
iterator(index);
function eachLimit(collection, limit, iterator, callback)
callback = callback || noop;
var size = collection.length;
var sync = false;
var started = 0;
var completed = 0;
timesSync(limit > size ? size : limit, iterate);
function iterate()
if (started < size)
iterator(collection[started++], done);
function done(err, bool)
if (err)
callback(err);
else if (++completed === size)
callback(null);
else
iterate();
我们都知道异步编程的方式有很多种,包括回调和 promise 的形式,下面是通过 promise 控制并发数量。
/**
* @params list Array - 要迭代的数组
* @params limit Number - 并发数量控制数
* @params asyncHandle Function - 对`list`的每一个项的处理函数,参数为当前处理项,必须 return 一个Promise来确定是否继续进行迭代
* @return Promise - 返回一个 Promise 值来确认所有数据是否迭代完成
*/
let eachLimit = (list, limit, asyncHandle) =>
let recursion = (arr) =>
return asyncHandle(arr.shift()).then((res) =>
// console.log(res)
if (arr.length !== 0)
return recursion(arr) // 数组还未迭代完,递归继续进行迭代
)
;
let listCopy = [].concat(list);
let asyncList = []; // 正在进行的所有并发异步操作
while (limit--)
asyncList.push(recursion(listCopy));
return Promise.all(asyncList); // 所有并发异步操作都完成后,本次并发控制迭代完成
const order = []
const timeout = i => new Promise(resolve =>
setTimeout(() =>
order.push(i)
resolve(i)
, i * 10)
);
eachLimit([1, 5, 3, 4, 2], 2, timeout).then((res) =>
console.log(order)
)
以上是关于neo-async 模块的主要内容,如果未能解决你的问题,请参考以下文章
Terraform 模块输出用作其他模块中的输入,特别是 for_each
将 aws 资源导入具有 for_each 的 terraform 模块