The task is to implement setInterval.
the boilerplate code
function mySetInterval(func, delay, period) {
// your code here
}
/**
* @param { number } id
*/
function myClearInterval(id) {
}
Create the global states
let nextId = 1;
const intervals = new Map()
nextId simulates browser-generated interval IDs and intervals keep track of active intervals.
Create a progressive interval
func mySetInterval(func, delay, period) {
Create an ID
const id = nextId++;
It ensures every interval has a unique identifier.
Create an interval state
const state = {
active: true,
count: 0,
timeoutId: null
}
active stops future executions when cleared. count is the number of times the function has been run. timeoutId is the current setTimeout reference.
Each period after every time the function runs is determined by
const waitTime = delay + period * state.count;
Execute and reschedule
state.timeoutId = setTimeout(() => {
if (!state.active) return;
func();
state.count++;
schedule();
}, waitTime);
Start the first timer
schedule();
intervals.set(id, state);
Return ID
return id;
To clear the interval after it runs
function myClearInterval(id) {
If the interval doesn't exist, do nothing
const state = intervals.get(id);
if (!state) return;
Stop future executions
state.active = false;
Cancel pending timeout
clearTimeout(state.timeoutId);
Remove the interval from tracking
intervals.delete(id);
The final code
let nextId = 1;
const intervals = new Map();
function mySetInterval(func, delay, period) {
// your code here
const id = nextId++;
const state = {
active: true,
count: 0,
timeoutId: null
}
function schedule() {
const waitTime = delay + period * state.count;
state.timeoutId = setTimeout(() => {
if(!state.active) return;
func();
state.count++;
schedule();
}, waitTime)
}
schedule();
intervals.set(id, state);
return id;
}
function myClearInterval(id) {
const state = intervals.get(id);
if(!state) return;
state.active = false;
clearTimeout(state.timeoutId);
intervals.delete(id)
}
That's all folks!
Top comments (0)