Skip to content

Instantly share code, notes, and snippets.

@UnluckyNinja
Created May 11, 2021 18:07
Show Gist options
  • Save UnluckyNinja/65c9480e998a2199573c743620de207d to your computer and use it in GitHub Desktop.
Save UnluckyNinja/65c9480e998a2199573c743620de207d to your computer and use it in GitHub Desktop.
A simple reactive timed queue that leverage vue 3 and vueuse
import { nextTick, readonly, ref, Ref } from 'vue'
import { until } from '@vueuse/core'
export function timeout(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export const createQueue = (minInterval: number = 0) => {
const queue = [] as { ready: Ref<boolean> }[]
let last = 0
const next = async () => {
let gap = Date.now() - last
if (gap < minInterval) {
await timeout(minInterval - gap)
}
const item = queue.shift()
if (item) {
item.ready.value = true
}
last = Date.now()
// avoid called at empty queue
if (queue.length === 0) {
return
}
setTimeout(() => { next() }, 0)
}
const useQueue = () => {
let ready = ref(false)
queue.push({ ready })
// call next when is empty queue (queue will stop when empty)
if (queue.length === 1) {
nextTick(() => next())
}
const untilReady = async () => {
await until(ready).toBe(true)
}
return { ready: readonly(ready), untilReady }
}
return useQueue
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment