Promise.all () with a limit?

Is there a way / template to implement let res = Promise.all([...p], limit)?

  • The promise array contains functions that build and return a promise
  • resshould be allowed after everything ppermits
  • Only limit=3Promises should work in parallel
  • n + 1st promise should begin immediately after the end of n. So there are always limitresolvers working in parallel.

Especially the last moment creates my headaches.

My current solution is to split the promises -array into size chunks limitand tie them together. The disadvantages here are that the second group does not start until all Promises from bundle 1 are resolved.

+4
source share
2 answers

The function sequenceWithParallelismin the bluebird-as extension seems to be designed specifically for the functions you want. As it is written, a blue bird is used to implement it, but I do not see anything specific for blue birds in the actual contents of the function sequenceWithParallelism, so you can simply extract this function and use it in your own code, for example:

sequenceWithParallelism(limit, f => f())([..p])
    .then(function () {

    });

Oddly enough, the function does not seem to be intended to resolve the results of all promises, so if you need it, you probably need to make a few changes.

+1
source

I came up with the idea of ​​creating chains n = limitthat work in parallel and are added as long as promises exist:

let promises = [];
for(let i=0; i<11; i++) promises[i] = () => {
  console.log('Construct:',i);
  return new Promise(resolve => {
    setTimeout(function() {
      console.log('Resolve:',i);
      resolve(i);
    }, Math.round(Math.random() * (2000 - 500) + 2000));
  });
}


function parallelLimit(promiseFactories, limit) {
  let result = [];
  let cnt = 0;

  function chain(promiseFactories) {
    if(!promiseFactories.length) return;
    let i = cnt++; // preserve order in result
    return promiseFactories.shift()().then((res) => {
      result[i] = res; // save result
      return chain(promiseFactories); // append next promise
    });
  }

  let arrChains = [];
  while(limit-- > 0 && promiseFactories.length > 0) {
    // create `limit` chains which run in parallel
    arrChains.push(chain(promiseFactories));
  }

  // return when all arrChains are finished
  return Promise.all(arrChains).then(() => result);
}


parallelLimit(promises, 4).then(console.log);
Run codeHide result

, :)

0

Source: https://habr.com/ru/post/1659589/


All Articles