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.