Skip to content

Instantly share code, notes, and snippets.

@softwarespot
Last active March 29, 2019 14:16
Show Gist options
  • Save softwarespot/151bdf45767392558f00a8c9b9ebcb8f to your computer and use it in GitHub Desktop.
Save softwarespot/151bdf45767392558f00a8c9b9ebcb8f to your computer and use it in GitHub Desktop.
Create an a queue that can be pushed to and processed asynchronously and in chunks
// Found similar article URL: https://humanwhocodes.com/blog/2009/08/11/timed-array-processing-in-javascript/
function createProcessingQueue(onHandleItem, onHandleTimeout, timeout = 50) {
const state = {
queue: [],
timerId: 0,
}
const api = {
push(...args) {
state.queue.push(...args)
},
start() {
if (state.timerId > 0) {
throw new Error(`Unable to start the queue, as currently processing`)
}
state.timerId = setTimeout(() => {
const endTime = Date.now() + timeout
const prevCount = state.queue.length
if (state.queue.length > 0) {
do {
const val = state.queue.shift()
onHandleItem(val)
} while (state.queue.length > 0 && endTime > Date.now())
const currCount = state.queue.length
const processCount = Math.min(prevCount, prevCount - currCount)
onHandleTimeout(processCount, currCount)
}
api.stop()
api.start()
})
},
stop() {
clearTimeout(state.timerId)
state.timerId = 0
},
}
api.start()
return api
}
// Example
function handleItem(item) {
console.log(item)
}
function handleTimeout(processCount, currCount) {
console.log(`Handle timeout: ${currCount} item(s) remaining and processed ${processCount}`)
console.log('Update the DOM')
}
const state = {
q: createProcessingQueue(handleItem, handleTimeout, 750),
id: 0,
}
setInterval(() => queueFill(500), 1000)
function queueFill(count) {
console.log(`Begin filling the queue with ${count} item(s)`)
for (let i = 0; i < count; i += 1) {
state.q.push(state.id++)
}
console.log(`Completed filling the queue with ${count} item(s)`)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment