uniform-scheduler
v1.0.0
Published
Simple JS scheduler
Downloads
4
Maintainers
Readme
Uniform Scheduler
Schedules dynamic number of similar tasks uniformly in time.
Check out an interactive demo.
Installation
Requires Node >= 20.
npm i uniform-scheduler
Usage
import { UniformScheduler } from 'uniform-scheduler';
/** Returns a promise that resolves after `duration` amount of milliseconds */
declare const sleep: (duration: number) => Promise<void>;
const scheduler = new UniformScheduler(100 /* minInterval, ms */);
const taskA = () => { console.log('task A called'); };
const taskB = () => { console.log('task B called'); };
/* Time(ms): */
scheduler.addTask(taskA); /* => 0| task A called */
await sleep(225); /* 25| */
/* 50| */
/* 75| */
/* 100| task A called */
/* | */
/* | */
/* | */
/* 200| task A called */
scheduler.addTask(taskB); /* => 225| */
await sleep(150); /* 250| task B called */
/* | */
/* 300| task A called, minInterval = 100ms for task A is preserved */
/* | */
/* 350| task B called, 2 tasks are now spread uniformly in time */
scheduler.removeTask(taskA); /* => 375| */
await sleep(100); /* 400| task A would've been called but was just removed */
/* | */
/* 450| task B called, minInterval for task B still preserved */
scheduler.stop(); /* => 475| scheduler stopped, no tasks will be called anymore */
Q&A
Q: Why is this useful?
A: One case I could think of is a web scraper that needs a low refresh latency.
Q: My tasks are drifting. The task that was supposed to run at t=250ms actually ran at t=251ms
A: The scheduler uses setTimeout
under the hood. And just like setTimeout
, it is a best-effort
API. The scheduler only calculates the time when a task is supposed to be run and then passes it to
setTimeout
without doing any additional event loop magic. Consequently, +-1ms drift is common.