Skip to content

Instantly share code, notes, and snippets.

@ccnokes ccnokes/RICScheduler.ts
Last active Feb 23, 2019

Embed
What would you like to do?
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
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
You can’t perform that action at this time.