crazy4groovy
1/20/2018 - 4:37 AM

A simple queue to throttle X simultaneous async function executions at a time.

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) {}