Last active
September 28, 2022 11:18
-
-
Save geovanisouza92/db8e9090a955bd05f8793b4643e74a0c to your computer and use it in GitHub Desktop.
You don't need bluebird / async
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function forEachSerial(cb, arr) { | |
await arr.reduce(async (prevPromise, value) => { | |
await prevPromise; | |
return cb(value); | |
}, Promise.resolve()); | |
} | |
async function forEachParallel(cb, arr) { | |
await Promise.all(arr.map(cb)); | |
} | |
async function forEachParallelWithLimit(cb, size, arr) { | |
const chunks = []; | |
for(let i = 0; i < arr.length; i += size) { | |
chunks.push(arr.slice(i, i + size)); | |
} | |
await forEachSerial(async (chunk) => { | |
await forEachParallel(cb, chunk); | |
}, chunks); | |
} | |
// Inspired by https://github.com/davetemplin/async-parallel/blob/68ccac12b94075252d0a8233756581b381e4b360/index.ts#L133 | |
async function forEachParallelWithConcurrentLimit(cb, size, arr) { | |
async function pool(size, task) { | |
let active = 0; | |
let done = false; | |
let errors = []; | |
return new Promise((resolve, reject) => { | |
next(); | |
async function next() { | |
const hasNotReachedLimit = active < size; | |
while (hasNotReachedLimit && !done) { | |
active++; | |
try { | |
const more = await task(); | |
const allTasksDone = --active === 0; | |
if (allTasksDone && (done || !more)) { | |
if (errors.length === 0) { | |
resolve(); | |
} else { | |
reject(new Error(`${errors.length} errors`)); | |
} | |
} else if (more) { | |
next(); | |
} else { | |
done = true; | |
} | |
} catch (err) { | |
errors.push(err); | |
done = true; | |
const allTasksDone = --active === 0; | |
if (allTasksDone) { | |
reject(new Error(`${errors.length} errors`)); | |
} | |
} | |
} | |
} | |
}); | |
} | |
// Copy source array | |
arr = arr.slice(); | |
// Allocate results array | |
const result = new Array(arr.length).fill(null); | |
let i = 0; | |
await pool(size, async () => { | |
if (arr.length > 0) { | |
const j = i++; | |
result[j] = await cb(arr.shift(), j, arr); | |
} | |
// Has more? | |
return arr.length > 0; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment