Tuesday, 30 November 2021

How promises inside for loop are working?

In my program source code I have the following function (Promise concurrency limitation function, similar to pLimit):

async function promiseMapLimit(
  array,
  poolLimit,
  iteratorFn,
) {
  const ret = [];
  const executing = [];
  for (const item of array) {
    const p = Promise.resolve().then(() => iteratorFn(item, array));
    ret.push(p);

    if (poolLimit <= array.length) {
      const e = p.then(() => executing.splice(executing.indexOf(e), 1));
      executing.push(e);
      if (executing.length >= poolLimit) {
        await Promise.race(executing);
      }
    }
  }

  return Promise.all(ret);
}

It works properly, so if I passed it an array of numbers [1..99] and try to multiply it by 2 it will give the correct output [0..198].

const testArray = Array.from(Array(100).keys());

promiseMapLimit(testArray, 20, async (value) => value * 2).then((result) =>
  console.log(result)
);

Code sample - js playground.

But I can't understand its logic, during the debugging I noticed, that it adds promises in chunks of 20 and only after that goes further: enter image description here

For example, this block of code:

  for (const item of array) {
    const p = Promise.resolve().then(() => iteratorFn(item, array));
    ret.push(p);

will iterate over 20 items of an array (why not all 100???)

same here:

if (poolLimit <= array.length) {
      const e = p.then(() => executing.splice(executing.indexOf(e), 1));
      executing.push(e);

it will add only 20 items to the executing array and only after that step inside if (executing.length >= poolLimit) code block.

I'd be very grateful for the explanation of how this function works.



from How promises inside for loop are working?

No comments:

Post a Comment