ES6承诺替换async.eachLimit / async.mapLimit [英] ES6 Promise replacement of async.eachLimit / async.mapLimit
问题描述
在异步中,如果我需要将一个异步功能应用于1000个项目,我可以做with:
async.mapLimit(items,10,(item,callback)=> {
foo item,callback);
});
,以便只同时处理10个项目,限制开销并允许控制。 >
随着ES6的承诺,我可以很容易地做到:
Promise.all items.map((item)=> {
return bar(item);
}));
将同时处理所有1000个项目,这可能会导致很多问题。 >
我知道蓝鸟有办法处理这个,但我正在搜索一个ES6解决方案。
没有内置的东西,但是你可以自己分组在链结的数组上使用 Promise.all
:
const items = / * ... 1000 items ... * /;
const concurrencyLimit = 10;
const promise = Promise.all(items.reduce((promises,item,index)=> {
//我们添加什么链?
const chainNum = index%concurrencyLimit ;
let chain = promises [chainNum];
if(!chain){
// New chain
chain = promises [chainNum] = Promise.resolve();
}
//添加
promises [chainNum] = chain.then(_ => foo(item));
return promises;
},[]) );
这是一个例子,显示了有多少并发承诺在给定的时间(并且还显示每个链完成,只做200而不是1,000):
const items = buildItems(); const concurrencyLimit = 10; const promise = Promise.all(items.reduce((promises,item,index)=> {const chainNum = index%concurrencyLimit; let chain = promises [ chainNum]; if(!chain){chain = promises [chainNum] = Promise.resolve();} promises [chainNum] = chain.then(_ => foo(item)); return promises;},[] .map(chain => chain.then(_ => console.log(Chain done)))); promise.then(_ => console.log(All done)); function buildItems ){const items = []; for(let n = 0; n <200; ++ n){items [n] = n; } return items;} var outstanding = 0; function foo(item){++ outstanding; console.log(Starting+ item +(+ outstanding +));返回新的Promise(resolve => {setTimeout(_ => {--outstanding; console.log(Resolving+ item +(+ outstanding +)); resolve(item);} random()* 500);});}
。 as-console-wrapper {max-height:100%!important;}
我应该注意,如果你想跟踪每一个的结果,你必须修改以上;它不会尝试跟踪结果(!)。 : - )
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);
});
so that only 10 item are processed at the same time, limiting overhead and allowing control.
With ES6 promise, while I can easily do:
Promise.all(items.map((item) => {
return bar(item);
}));
that would process all 1000 items at the same time which may cause a lot of problems.
I know Bluebird have ways to handle that, but I am searching a ES6 solution.
There's nothing built in, but you can of course group them yourself into promise chains, and use a Promise.all
on the resulting array of chains:
const items = /* ...1000 items... */;
const concurrencyLimit = 10;
const promise = Promise.all(items.reduce((promises, item, index) => {
// What chain do we add it to?
const chainNum = index % concurrencyLimit;
let chain = promises[chainNum];
if (!chain) {
// New chain
chain = promises[chainNum] = Promise.resolve();
}
// Add it
promises[chainNum] = chain.then(_ => foo(item));
return promises;
}, []));
Here's an example, showing how many concurrent promises there are any given time (and also showing when each "chain" is complete, and only doing 200 instead of 1,000):
const items = buildItems();
const concurrencyLimit = 10;
const promise = Promise.all(items.reduce((promises, item, index) => {
const chainNum = index % concurrencyLimit;
let chain = promises[chainNum];
if (!chain) {
chain = promises[chainNum] = Promise.resolve();
}
promises[chainNum] = chain.then(_ => foo(item));
return promises;
}, []).map(chain => chain.then(_ => console.log("Chain done"))));
promise.then(_ => console.log("All done"));
function buildItems() {
const items = [];
for (let n = 0; n < 200; ++n) {
items[n] = n;
}
return items;
}
var outstanding = 0;
function foo(item) {
++outstanding;
console.log("Starting " + item + " (" + outstanding + ")");
return new Promise(resolve => {
setTimeout(_ => {
--outstanding;
console.log("Resolving " + item + " (" + outstanding + ")");
resolve(item);
}, Math.random() * 500);
});
}
.as-console-wrapper {
max-height: 100% !important;
}
I should note that if you want to track the result of each of those, you'd have to modify the above; it doesn't try to track the results (!). :-)
这篇关于ES6承诺替换async.eachLimit / async.mapLimit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!