/
githubmirror
/
gitness
Обзор
Документация
Войти
/
githubmirror
/
gitness
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
web/src/utils/Task.ts
74 строки
2 KB
Tan Nhu
Show full diff in Pull Request + 10k files PR challenge (#1086)
01 мар 2024, 22:42
01 мар 2024, 22:42
a164636
Код
Авторство
О чём код?
type Task = () => void type RunnerType = 'requestAnimationFrame' | 'requestIdleCallback' | 'setTimeout' function createTaskPool(type: RunnerType = 'requestAnimationFrame', blockSize: number) { const tasks: Array<[Task, number]> = [] const runner = type === 'requestAnimationFrame' ? requestAnimationFrame : window.requestIdleCallback let id = 1 let running = false const scheduleTask = (task: Task, priority = tasks.length) => { id = id + 1 < Number.MAX_SAFE_INTEGER ? id + 1 : 1 tasks.splice(priority, 0, [task, id]) run() return id } const run = () => { if (!running && tasks.length) { running = true const block = tasks.splice(0, blockSize) const blockTracking = block.map(_ => { let resolve: (value: unknown) => void = noop new Promise(_resolve => (resolve = _resolve)) return { resolve } }) block.forEach((task, idx) => runner(() => blockTracking[idx].resolve(task[0]?.()))) Promise.all(blockTracking).then(() => { running = false if (tasks.length) run() }) } } const cancelTask = (taskId: number) => { const index = tasks.findIndex(([, _id]) => _id === taskId) if (index > -1) tasks.splice(index, 1) } return { scheduleTask, cancelTask } } const EXECUTION_BLOCK_SIZE = 10 const noop = () => 0 export const createRequestAnimationFrameTaskPool = (blockSize = EXECUTION_BLOCK_SIZE) => createTaskPool('requestAnimationFrame', blockSize) export const createRequestIdleCallbackTaskPool = (blockSize = EXECUTION_BLOCK_SIZE) => createTaskPool('requestIdleCallback', blockSize) // Polly fill requestIdleCallback/cancelIdleCallback for Safari window.requestIdleCallback = window.requestIdleCallback || function (cb) { const start = Date.now() return setTimeout(function () { cb({ didTimeout: false, timeRemaining: function () { return Math.max(0, 50 - (Date.now() - start)) } }) }, 1) } window.cancelIdleCallback = window.cancelIdleCallback || function (id) { clearTimeout(id) }