A simple queue to throttle X simultaneous async function executions at a time.
const createQueue = (maxOutstanding = 10, log) => {
const queue = []
let outstanding = 0
async function scheduleWork() {
if ((outstanding >= maxOutstanding) || queue.length === 0) return
outstanding++
const { func, args, resolve, reject } = queue.shift()
try {
log && log('[Q] WORK STARTED:', outstanding, queue.length)
resolve(await func(...args)) // handle async AND sync functions
} catch (err) {
log && log('[Q] !! WORK ERROR:', err.message, func.name)
reject(err)
}
outstanding--
log && log('[Q] WORK ENDED: ', outstanding, queue.length)
scheduleWork() // schedule next func exec
}
return (func) => (...args) => {
return new Promise((resolve, reject) => {
queue.push({ func, args, resolve, reject })
scheduleWork() // schedule next func exec
})
}
}
try { module.exports = createQueue } catch (ignore) {}