ES6 Promise 替换 async.eachLimit/async.mapLimit [英] ES6 Promise replacement of async.eachLimit / async.mapLimit
问题描述
在 async 中,如果我需要对 1000 个项目应用异步函数,我可以这样做与:
In async, if I need to apply a asynchronousfunction to 1000 items, I can do that with:
async.mapLimit(items, 10, (item, callback) => {
foo(item, callback);
});
这样只能同时处理 10 个项目,从而限制开销并允许控制.
so that only 10 item are processed at the same time, limiting overhead and allowing control.
使用 ES6 承诺,而我可以轻松做到:
With ES6 promise, while I can easily do:
Promise.all(items.map((item) => {
return bar(item);
}));
这会同时处理所有 1000 个项目,这可能会导致很多问题.
that would process all 1000 items at the same time which may cause a lot of problems.
我知道Bluebird 有办法处理这个问题,但我正在搜索 ES6解决方案.
I know Bluebird have ways to handle that, but I am searching a ES6 solution.
推荐答案
如果你不关心结果,那么快速搞定一个:
If you don't care about the results, then it's quick to whip one up:
Promise.eachLimit = async (funcs, limit) => {
let rest = funcs.slice(limit);
await Promise.all(funcs.slice(0, limit).map(async func => {
await func();
while (rest.length) {
await rest.shift()();
}
}));
};
// Demo:
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
async function foo(s) {
await wait(Math.random() * 2000);
console.log(s);
}
(async () => {
let funcs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").map(s => () => foo(s));
await Promise.eachLimit(funcs, 5);
})();
一个关键性能属性是在任何函数完成后立即运行下一个可用函数.
A key performance property is running the next available function as soon as any function finishes.
按顺序保留结果可能会使它不那么优雅,但还不错:
Preserving the results in order makes it a little less elegant perhaps, but not too bad:
Promise.mapLimit = async (funcs, limit) => {
let results = [];
await Promise.all(funcs.slice(0, limit).map(async (func, i) => {
results[i] = await func();
while ((i = limit++) < funcs.length) {
results[i] = await funcs[i]();
}
}));
return results;
};
// Demo:
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
async function foo(s) {
await wait(Math.random() * 2000);
console.log(s);
return s.toLowerCase();
}
(async () => {
let funcs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").map(s => () => foo(s));
console.log((await Promise.mapLimit(funcs, 5)).join(""));
})();
这篇关于ES6 Promise 替换 async.eachLimit/async.mapLimit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!