Last active
February 23, 2019 22:14
-
-
Save ccnokes/d6ef6ad42e46a1bf475823267c8c3a52 to your computer and use it in GitHub Desktop.
RequestIdleCallback scheduler. Create an instance and use it globally to ensure that tasks are efficiently run in as few requestIdleCallbacks as possible (as described here https://developers.google.com/web/updates/2015/08/using-requestidlecallback). Sandbox: https://codesandbox.io/s/r45rv9lv1o
This file contains 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
class RICScheduler { | |
private queue: { task: () => void, id: number }[] = []; | |
private running = false; | |
private nextId = 0; | |
private ricId; | |
private id() { | |
return this.nextId++; | |
} | |
// returns unsubscribe function | |
add(fn: () => void) { | |
let taskConfig = { task: fn, id: this.id() }; | |
this.queue.push(taskConfig); | |
if (!this.running) { | |
this.run(); | |
} | |
return () => this.cancel(taskConfig.id); | |
} | |
private cancel(id: number) { | |
let index = this.queue.findIndex(item => item.id === id); | |
if (index !== -1) { | |
this.queue.splice(index, 1); | |
} | |
} | |
clearAll() { | |
cancelIdleCallback(this.ricId); | |
this.queue = []; | |
this.running = false; | |
} | |
private run() { | |
this.running = true; | |
this.ricId = requestIdleCallback((deadline) => { | |
let taskCount = 0; | |
while (deadline.timeRemaining() > 0 && this.queue.length) { | |
let { task } = this.queue.shift(); | |
task(); | |
taskCount++; | |
} | |
// if there's still tasks remaining, schedule another run | |
if (this.queue.length > 0) { | |
this.run(); | |
} else { | |
this.running = false; | |
} | |
}); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment