Skip to content

Instantly share code, notes, and snippets.

@hunan-rostomyan
Last active September 30, 2021 06:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hunan-rostomyan/af0eea8eccf7b96ea43805ad98f2a803 to your computer and use it in GitHub Desktop.
Save hunan-rostomyan/af0eea8eccf7b96ea43805ad98f2a803 to your computer and use it in GitHub Desktop.
A setTimeout with delay
// Scheduler is setTimeout with an ability to delay
// already scheduled tasks.
// 1. DEFINITION
// -------------
function Scheduler(freq) { // freq in ms
this.freq = freq;
setInterval(this._main.bind(this), this.freq);
}
Scheduler.prototype._main = function() {
if (this.t) {
if (this.t === this.freq) {
this.fn();
}
this.t -= this.freq;
}
};
// Works just like setTimeout.
Scheduler.prototype.assign = function(fn, t) {
if (t % this.freq !== 0) {
throw new Error('assign(fn, t): t must be a multiple of freq');
}
this.fn = fn;
this.t = this.max = t;
};
// Delay the task by t (if t < max) or max.
Scheduler.prototype.delay = function(t) {
if (this.t) {
this.t = Math.min(this.max, this.t + t);
}
};
// 2. USAGE
// --------
// Instantiate a scheduler that runs things every second.
var s = new Scheduler(1000);
// Schedule 'hi' to be displayed in 5 seconds.
s.assign(function() {console.log('hi');}, 5000);
// Suppose 1 second remained for 'hi' to be displayed;
// now it will display in 3 seconds (unless delayed again).
s.delay(2000);
// Note that you can keep delaying a task, but it will always be
// bounded by the originally scheduled time (here, 5 seconds).
// Scheduler in TypeScript
export class Scheduler {
fn: Function; // function to call when time comes
freq: number; // in ms
t_orig: number; // original time scheduled
t: number; // time scheduled
constructor(freq: number) {
this.freq = freq;
setInterval(this._loop.bind(this), this.freq);
}
_loop() {
if (this.t) {
if (this.t === this.freq) {
this.fn();
}
this.t -= this.freq;
}
}
// Works just like setTimeout.
assign(fn: Function, t: number) {
if (t % this.freq !== 0) {
throw new Error('assign(fn, t): t must be a multiple of freq');
}
this.fn = fn;
this.t = this.t_orig = t;
}
// Delay the task by t (if t < t_orig) or t_orig.
delay(t: number) {
if (this.t) {
this.t = Math.min(this.t_orig, this.t + t);
}
}
}
import { Scheduler } from "./scheduler";
// Instantiate a scheduler that runs things every second.
var s = new Scheduler(1000);
// Schedule 'hi' to be displayed in 5 seconds.
s.assign(() => console.log('hi'), 5000);
// Suppose 1 second remained for 'hi' to be displayed;
// now it will display in 3 seconds (unless delayed again).
s.delay(2000);
// Note that you can keep delaying a task, but it will always be
// bounded by the originally scheduled time (here, 5 seconds).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment