concurrency-limit-javascript-question

this is used for phone screening

by upigilam

JavaScript

function expensiveAsyncFunction(delay = 1000) {
console.log('upendra :: expensiveAsyncFunction')
  return new Promise((resolve) => {
    // resolve with a value
    setTimeout(() => resolve(Date.now()), delay);
  });
}

// collection of 50 async functions
const asyncFunctions = [];
for (let i = 0; i < 50; i++) {
  asyncFunctions.push(expensiveAsyncFunction);
}

// main function
// you can change the concurrencyLimit to what ever you want.
async function processByBatch(asyncFunctions, concurrencyLimit = 13) {
console.log('upendra :: processByBatch')
  let allResponses = [];
  let batch = [];
  
  console.log('upendra :: all async fun :: ',  asyncFunctions)

  for (let func of asyncFunctions) {
        console.log('upendra:: i am forloop :: batch length ', batch.length)
    if (batch.length < concurrencyLimit) {
      batch.push(func);
    } else {
    console.log('upendra:: i am in else :: batch ::', batch)
      console.log('upendra:: i am in else :: length ::', batch.length)
      allResponses = allResponses.concat(await processBatch(batch));
      batch = [func];
          console.log('upendra:: i am in else end :: batch ::', batch)
    }
  }

  // handle remainder when concurrencyLimit does not evenly divide
  if (batch.length) {
  console.log('upendra:: i am remainder :: batch.length :: ', batch.length)
    allResponses = allResponses.concat(await processBatch(batch));
  }

  return allResponses;
}

// helper function
async function processBatch(asyncFunctions) {
  const invokedFunctions = asyncFunctions.map((fun) => fun());
  const response = await Promise.all(invokedFunctions);
  console.log("upendra :: batch is done processing!", response);
  return response;
}

// verify the function works
processByBatch(asyncFunctions).then((response) => {
  console.log("upendra :: yay it finished!", response.length);
});