当前位置: 首页 > 知识库问答 >
问题:

ES6promise更换async.each/async.map限制

虞祯
2023-03-14

在async中,如果我需要将asynchronousfunction应用于1000个项目,我可以使用:

async.mapLimit(items, 10, (item, callback) => {
    foo(item, callback);
});

因此,同一时间只处理10个项目,从而限制开销并允许控制。

有了ES6的promise,虽然我可以很容易地做到:

Promise.all(items.map((item) => {
    return bar(item);
}));

这将同时处理所有1000个项目,这可能会导致很多问题。

我知道蓝鸟有办法解决这个问题,但我正在寻找ES6解决方案。

共有3个答案

白越
2023-03-14

使用rray.prototype.splice

while (funcs.length) {
  await Promise.all( funcs.splice(0, 100).map(f => f()) )
}
裴甫
2023-03-14

没有内置内容,但是您当然可以将它们自己分组到promise链中,并在生成的链数组上使用Promise.all:

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;
}, []));

下面是一个示例,显示在给定时间内有多少并发promise(还显示每个“链”何时完成,并且只执行200而不是1000):

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;
}
尚嘉庆
2023-03-14

如果你不在乎结果,那么很快就会想出一个:

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只在另一个promise之后运行()。 由于某种原因,我找不到一个方法来做这件事。 我尝试了生成器函数(),尝试了返回promise的简单函数,但最终都归结为同一个问题:循环是同步的。 对于async,我只需使用。 你怎么解决?

  • 动态规划变更问题(有限硬币)。我正在尝试创建一个以以下内容作为输入的程序: 输出: 输出应该是大小为1的数组,其中每个单元格代表我们需要改变单元格索引量的最佳硬币数。 假设数组的单元格位于index: 5,内容为2。这意味着为了给出5(INDEX)的变化,您需要2(单元格的内容)硬币(最佳解决方案)。 基本上,我需要这个视频的第一个数组的输出(C[p])。这与有限硬币的大区别是完全相同的问题。链接

  • 我是一个完整的打字初学者,我想知道是否有可能在打字中使用ES6promise,以及我必须做什么才能让他们工作。我正在运行节点0.11.14,在编译过程中得到一个错误“不能找到名称'promise'”

  • 我正在替换一些使用jQuery延迟对象的旧代码,并且正在使用Bluebird/ES6承诺进行重写。 如果我有多个异步调用,那么在所有承诺都解决之后,我如何触发一个函数。 使用jQuery可以进行延迟: 我如何使用ES6 Promise语法重写它?

  • 问题内容: JMF很老,并且不正确地支持许多编解码器。这些天我在后台使用了FFMPEG,但我想切换到本机Java解决方案(如果存在),有人知道当前具有媒体处理功能的开源Java项目吗? 问题答案: 这取决于您要做什么。 由于您使用的是ffmpeg,因此我假设您正在编码视频。我感到悲观的是,Java将在短期或中期执行此类“本机”工作-这与许多Java理念/包very大相径庭。 就是说,使用Java

  • 具体而言,问题是: 给定面额数组<代码>硬币[],每个硬币的限制数组<代码>限制[]和数量<代码>金额,返回所需的最小硬币数量,以获取<代码>金额,或者如果不可能,返回空值。另外,用溶液中使用的每个硬币的数量填充数组 这是我的解决方案: 但它一般不起作用。 我的问题是,例如,在这种情况下: 最佳解决方案是: 并且我的算法给出作为结果。换句话说,它失败了,每当在某种情况下,我将不得不使用比可能的更少