0

Imagine a request triggered with:

http.get('/endpoint')

Imagine 10 requests triggered with:

const promises = _.range(10).map(i => http.get('/endpoint'))

If I want to execute all the requests simultaneously, I generally use

const results = await Promise.all(promises)

Now, let's imagine that I want to only execute 2 requests at a time, will Promise.all() on only two items be enough to execute only 2 requests at a time or will still all requests be triggered at the same time?

const promises = _.range(10).map(i => http.get('/endpoint'))

let results = []

for (let chunk of _.chunk(promises, 2)) {
  results = results.concat(await Promise.all(chunk))
}

If it still executes the 10 requests at the same time, how could I prevent this behavior?

Note: _ refers to the lodash library in order to make the question simpler

Hammerbot
  • 15,696
  • 9
  • 61
  • 103
  • Hi, If you really want to run two requests at a time. Why not just execute and wait two requests in a loop ? – kucing_terbang Mar 26 '19 at 14:55
  • `Promise.all` does not "run" anything. You cannot "execute" promises, you can only wait for them. If you already called `http.get()` 10 times in the loop, you have started 10 concurrent requests. `Promise.all` only waits for them. – Bergi Mar 26 '19 at 15:00
  • Thank you, that was my question :) – Hammerbot Mar 26 '19 at 15:01
  • Possible duplicate of [Limited parallelism with async/await in Typescript/ES7](https://stackoverflow.com/a/39197252/1048572) – Bergi Mar 26 '19 at 15:01
  • A simple solution would be to move the `.map(i => http.get('/endpoint'))` onto `chunk` (inside the loop) – Bergi Mar 26 '19 at 15:02
  • Yes indeed, I should create the initial array on the parameters of the `http.get` function instead of the result of the function I guess – Hammerbot Mar 26 '19 at 15:03

2 Answers2

2

Use bluebird Promise.map that allow to configure concurrency - the concurrency limit applies to Promises returned by the mapper function and it basically limits the number of Promises created.

Promise.map(_.range(10), () => {...}, {concurrency: 2})
zooblin
  • 2,172
  • 2
  • 27
  • 33
1

You can use mapLimit from async. https://caolan.github.io/async/docs.html#mapLimit

import mapLimit from 'async/mapLimit';

const ids = _.range(10);
const maxParallel = 2;

mapLimit(ids, maxParallel, (id, callback) => {
  http.get(`/endpoint/${id}`)
    .then(result => callback(null, result))
    .catch(error => callback(error, null));
}, (error, results) {
 //Some stuff
});

Nautilus
  • 11
  • 3