Skip to content

Instantly share code, notes, and snippets.

@seveibar
Created April 14, 2017 23:37
Show Gist options
  • Save seveibar/ba10d775157d806303fb083f63f04341 to your computer and use it in GitHub Desktop.
Save seveibar/ba10d775157d806303fb083f63f04341 to your computer and use it in GitHub Desktop.
Resolve promises serially, with a given number in parallel
// @flow
export const serialResolve = (functionsReturningPromises: Array<() => Promise<any>>, parallelTasks: number) => new Promise((resolve, reject) => {
let tasksStarted = 0;
// Create empty results array
const results = Array.from(functionsReturningPromises, () => null);
const totalFunctions = functionsReturningPromises.length;
// When a promise completes, set the correct results index and start any additional tasks
let completedPromises = 0;
const promiseCompleted = (index:number) => (result: any) => {
results[index] = result;
completedPromises += 1;
if (completedPromises === totalFunctions) {
resolve(results);
}
if (tasksStarted < totalFunctions) {
tasksStarted += 1;
functionsReturningPromises[tasksStarted - 1]()
.then(promiseCompleted(tasksStarted - 1))
.catch(reject);
}
};
// Run the first PARALLEL_TASKS tasks
for (let i = 0;i < parallelTasks; i += 1) {
tasksStarted += 1;
functionsReturningPromises[i]()
.then(promiseCompleted(tasksStarted - 1))
.catch(reject);
}
});
export default serialResolve;
if (!module.parent) {
const compute = (a) => new Promise(resolve => {
setTimeout(() => {
console.log(`COMPUTED TASK ${a}`);
resolve(a + 1);
}, Math.random() * 500);
});
// Use like this
// const tasks = [0,1,2,3,4,5,6,7].map(a => () => compute(a))
// serialResolve(tasks, 3).then(console.log);
// Or like this
const taskParams = [0, 1, 2, 3, 4, 5, 6, 7];
serialResolve(taskParams.map((a) => () => compute(a)), 3).then(console.log);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment