Promises in Serial

A while back, I discovered I needed to run a series of promises in serial to avoid flooding an external service with too many requests. Given a function that calls the external service:

const requestToExternalService = function(d) {
  // Replace with a promise that does real work here...
  return new Promise(resolve => {
    console.log(d);

    // Delay demonstrates we are indeed batching
    setTimeout(resolve, 250);
  });
};

Here’s a way to run multiple promises in serial:

// Replace with real data
const data = [...Array(5).keys()];

let promiseChain = Promise.resolve();
data.forEach(d =>
  promiseChain = promiseChain.then(() => requestToExternalService(d))
);

promiseChain.then(() => console.log('done'));

Here’s a way to run multiple promises in serial in batches of 5:

// Replace with real data
const BATCH_SIZE = 5;
const data = [...Array(21).keys()];

let promiseChain = Promise.resolve();
for(let i = 0; i < data.length; i += BATCH_SIZE) {
  promiseChain = promiseChain
    .then(() => Promise.all(
      data
        .slice(i, i + BATCH_SIZE)
        .map(d => requestToExternalService(d))
    ));
}

promiseChain.then(() => console.log('done'));

Full example is available in gist form.

Software Developer | Lifelong Learner. neverendingqs.com