Skip to content

Instantly share code, notes, and snippets.

@uhop
Created June 28, 2022 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uhop/955e68a73df2964e94271b189d9d1750 to your computer and use it in GitHub Desktop.
Save uhop/955e68a73df2964e94271b189d9d1750 to your computer and use it in GitHub Desktop.
// runs asynchronous operations in parallel, no more than a specified number at a time
// it takes an array of functions, which return promises when invoked without arguments
// modelled after Promise.all()
const wrap = value => {
if (typeof value == 'function') return value();
if (value && typeof value.then == 'function') return value; // thenable
return Promise.resolve(value);
};
const batch = (fns, limit = 4) => {
if (limit < 1) limit = 1;
const result = [];
let next = limit,
available = limit;
const saveResult = (index, resolve, reject) => value => {
result[index] = value;
if (next < fns.length) {
wrap(fns[next]).then(saveResult(next, resolve, reject), reject);
++next;
} else {
++available;
if (available === limit) {
// we are done
resolve(result);
}
}
};
return new Promise((resolve, reject) => {
// start the pump
for (let i = 0, n = Math.min(fns.length, limit); i < n; ++i) {
wrap(fns[i]).then(saveResult(i, resolve, reject), reject);
--available;
}
});
};
export default batch;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment