以小并发批方式运行承诺(一次不超过X个)

Running promises in small concurrent batches (no more than X at a time)

本文关键字:一次 不超过 方式 运行 承诺 并发      更新时间:2023-09-26

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。

我想做同样的事情,但与承诺。

在Bluebird API中,我看不到任何明显的方法可以像Async那样简洁、富有表现力地完成这种批处理。

对于Bluebird(或一般的Promises)是否有一个好的模式?或者我可以使用的任何其他实用程序库?

在Bluebird中,您可以使用Promise.map函数和concurrency选项,如下所示

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" />