【问题标题】:Running promises in small concurrent batches (no more than X at a time)以小并发批次运行 Promise(一次不超过 X)
【发布时间】:2015-08-22 20:59:21
【问题描述】:

Async 库具有 eachLimit 之类的函数,可用于在多个 CPU 内核上高效地分发大量作业,如下所示:

var numCPUs = require('os').cpus().length;
var exec = require('child_process').exec;

async.eachLimit(someArray, numCPUs, function (value, done) {
  exec('something --input' + value, done);
}, finalCallback);

这避免了一次使用太多命令使系统过载,但仍会利用多个 CPU。

我想做同样的事情,但使用 Promises。

Bluebird API 中,我看不到任何明显的方法可以像使用异步一样以如此简洁、富有表现力的方式进行这种批处理。

有没有用 Bluebird(或一般的 Promises)做这件事的好模式?或者我可以为此使用的任何其他实用程序库?

【问题讨论】:

标签: javascript node.js asynchronous promise bluebird


【解决方案1】:

在Bluebird中,你可以使用Promise.map function with the concurrency option,像这样

require('bluebird').map([1, 2, 3, 4, 5, 6], function (currentNumber) {
    console.log(currentNumber);
    return Promise.delay(currentNumber * 2, 1000);
}, {concurrency: 2}).then(console.error.bind(console));

现在,您可以看到它一次处理两个值。正在处理的值可能有不同的顺序,但结果数组中的项目将与原始数组对应的顺序相同。

PS:我用Promise.delay引入了1秒的延迟,以便我们观察当前正在处理的内容。


演示

function start() {
  document.getElementById("result").innerHTML = "";

  Promise.map([1, 2, 3, 4, 5, 6], function(currentNumber) {
    document.getElementById("result").innerHTML += currentNumber + "<br />";
    return Promise.delay(currentNumber * 2, 1000);
  }, {
    concurrency: parseInt(document.getElementById("concurrency").value, 10)
  }).then(function(result) {
    document.getElementById("result").innerHTML += result + "<br />";
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.27/bluebird.min.js"></script>
Limit: <input id="concurrency" value="2" />
<input type="button" onclick="start()" value="Start" />
<pre id="result" />

【讨论】:

  • 但这如何利用 CPU 内核?
  • javascript 使用多个 CPU 内核的唯一方法是,如果每个 Promise 产生一个命令进程并等待它完成。
猜你喜欢
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 2012-11-02
  • 1970-01-01
相关资源
最近更新 更多