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

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

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