Created
May 11, 2021 18:07
-
-
Save UnluckyNinja/65c9480e998a2199573c743620de207d to your computer and use it in GitHub Desktop.
A simple reactive timed queue that leverage vue 3 and vueuse
This file contains hidden or 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
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