ES6承诺替换async.eachLimit / async.mapLimit [英] ES6 Promise replacement of async.eachLimit / async.mapLimit

查看:220
本文介绍了ES6承诺替换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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆