优化后台业务
This commit is contained in:
113
frontend-vue/src/shared/utils/categorized-timers.ts
Normal file
113
frontend-vue/src/shared/utils/categorized-timers.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
type TimerKind = 'timeout' | 'interval'
|
||||
type TimerCancel = () => void
|
||||
|
||||
interface TimerEntry {
|
||||
id: number
|
||||
kind: TimerKind
|
||||
category: string
|
||||
cancel?: TimerCancel
|
||||
}
|
||||
|
||||
const timerBuckets = new Map<string, Map<number, TimerEntry>>()
|
||||
|
||||
function bucketOf(category: string) {
|
||||
let bucket = timerBuckets.get(category)
|
||||
if (!bucket) {
|
||||
bucket = new Map<number, TimerEntry>()
|
||||
timerBuckets.set(category, bucket)
|
||||
}
|
||||
return bucket
|
||||
}
|
||||
|
||||
function removeTimer(category: string, id: number) {
|
||||
const bucket = timerBuckets.get(category)
|
||||
if (!bucket) return
|
||||
bucket.delete(id)
|
||||
if (!bucket.size) timerBuckets.delete(category)
|
||||
}
|
||||
|
||||
export function setCategorizedTimeout(category: string, handler: () => void, delayMs: number) {
|
||||
const id = window.setTimeout(() => {
|
||||
removeTimer(category, id)
|
||||
handler()
|
||||
}, delayMs)
|
||||
bucketOf(category).set(id, { id, kind: 'timeout', category })
|
||||
return id
|
||||
}
|
||||
|
||||
export function setCategorizedInterval(category: string, handler: () => void, delayMs: number) {
|
||||
const id = window.setInterval(handler, delayMs)
|
||||
bucketOf(category).set(id, { id, kind: 'interval', category })
|
||||
return id
|
||||
}
|
||||
|
||||
export function clearCategorizedTimer(category: string, id: number | null | undefined) {
|
||||
if (id == null) return
|
||||
const bucket = timerBuckets.get(category)
|
||||
const entry = bucket?.get(id)
|
||||
if (entry?.kind === 'interval') window.clearInterval(id)
|
||||
else window.clearTimeout(id)
|
||||
entry?.cancel?.()
|
||||
removeTimer(category, id)
|
||||
}
|
||||
|
||||
export function clearCategorizedTimers(category: string) {
|
||||
const bucket = timerBuckets.get(category)
|
||||
if (!bucket) return
|
||||
for (const entry of bucket.values()) {
|
||||
if (entry.kind === 'interval') window.clearInterval(entry.id)
|
||||
else window.clearTimeout(entry.id)
|
||||
entry.cancel?.()
|
||||
}
|
||||
timerBuckets.delete(category)
|
||||
}
|
||||
|
||||
export function sleepWithCategory(category: string, delayMs: number) {
|
||||
return new Promise<void>((resolve) => {
|
||||
const id = window.setTimeout(() => {
|
||||
removeTimer(category, id)
|
||||
resolve()
|
||||
}, delayMs)
|
||||
bucketOf(category).set(id, { id, kind: 'timeout', category, cancel: resolve })
|
||||
})
|
||||
}
|
||||
|
||||
export function clearTimerScope(scope: string) {
|
||||
const prefix = `${scope}:`
|
||||
for (const category of Array.from(timerBuckets.keys())) {
|
||||
if (category === scope || category.startsWith(prefix)) {
|
||||
clearCategorizedTimers(category)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createCategorizedTimers(scope: string) {
|
||||
const key = (category: string) => `${scope}:${category}`
|
||||
return {
|
||||
setTimeout(category: string, handler: () => void, delayMs: number) {
|
||||
return setCategorizedTimeout(key(category), handler, delayMs)
|
||||
},
|
||||
setInterval(category: string, handler: () => void, delayMs: number) {
|
||||
return setCategorizedInterval(key(category), handler, delayMs)
|
||||
},
|
||||
clearTimer(category: string, id: number | null | undefined) {
|
||||
clearCategorizedTimer(key(category), id)
|
||||
},
|
||||
clearCategory(category: string) {
|
||||
clearCategorizedTimers(key(category))
|
||||
},
|
||||
clearScope() {
|
||||
clearTimerScope(scope)
|
||||
},
|
||||
sleep(category: string, delayMs: number) {
|
||||
return sleepWithCategory(key(category), delayMs)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function getCategorizedTimerStats() {
|
||||
return Array.from(timerBuckets.entries()).map(([category, bucket]) => ({
|
||||
category,
|
||||
count: bucket.size,
|
||||
}))
|
||||
}
|
||||
Reference in New Issue
Block a user