在async ,如果我需要将异步函数应用于 1000 个项目,我可以这样做:
async.mapLimit(items, 10, (item, callback) => {
foo(item, callback);
});
以便同时处理 10 个项目,限制开销并允许控制。
使用 ES6 promise,虽然我可以轻松做到:
Promise.all(items.map((item) => {
return bar(item);
}));
这将同时处理所有 1000 个项目,这可能会导致很多问题。
我知道Bluebird have ways to handle that ,但我正在寻找 ES6 解决方案。
最佳答案
如果你不关心结果,那么很快就可以做出来了:
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);
})();
一个关键性能属性是在任何函数完成后立即运行下一个可用函数。
保存结果
按顺序保留结果可能会使它不那么优雅,但还算不错:
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(""));
})();
关于javascript - ES6 Promise 替换 async.eachLimit/async.mapLimit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43892296/