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

cal*_*lum 10 javascript asynchronous node.js promise bluebird

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);
Run Code Online (Sandbox Code Playgroud)

这可以避免一次过多的命令使系统过载,但仍会利用多个CPU.

我想用Promises做同样的事情.

Bluebird API中,我看不到任何明显的方式来使用Async这样简洁,富有表现力的方式进行这种批处理.

使用Bluebird(或通常使用Promise)有一个很好的模式吗?或者我可以使用的任何其他实用程序库?

the*_*eye 10

在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));
Run Code Online (Sandbox Code Playgroud)

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

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


演示

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 />";
  });
}
Run Code Online (Sandbox Code Playgroud)
<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" />
Run Code Online (Sandbox Code Playgroud)