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

若如初见. 提交于 2020-01-03 07:21:25

问题


The Async library has functions like eachLimit which can be used to efficiently spread a big batch of jobs over multiple CPU cores, like this:

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);

This avoids overloading the system with too many commands at once, but still exploits multiple CPUs.

I want to do the same thing but with Promises.

In the Bluebird API, I can't see any obvious way to do this kind of batching in such a concise, expressive way as with Async.

Is there a good pattern for doing this with Bluebird (or with Promises generally)? Or any other utility library I could use for this?


回答1:


In Bluebird, you can use Promise.map function with the concurrency option, like this

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));

Now, you can see that it is processing two values at a time. The value being processed may be in a different order, but the items in the result array will be in the same order corresponding to the original array.

PS: I introduced a delay of 1 second with Promise.delay, so that we can observe what is being processed currently.


Demo

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


来源:https://stackoverflow.com/questions/30708383/running-promises-in-small-concurrent-batches-no-more-than-x-at-a-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!