DEV Community

Bukunmi Odugbesan
Bukunmi Odugbesan

Posted on

Coding Challenge Practice - Question 112

The task is to implement setInterval.

the boilerplate code

function mySetInterval(func, delay, period) {
  // your code here
}

/**
 * @param { number } id
 */
function myClearInterval(id) {

}
Enter fullscreen mode Exit fullscreen mode

Create the global states

let nextId = 1;
const intervals = new Map()
Enter fullscreen mode Exit fullscreen mode

nextId simulates browser-generated interval IDs and intervals keep track of active intervals.

Create a progressive interval

func mySetInterval(func, delay, period) {
Enter fullscreen mode Exit fullscreen mode

Create an ID

const id = nextId++;
Enter fullscreen mode Exit fullscreen mode

It ensures every interval has a unique identifier.

Create an interval state

const state = {
  active: true,
  count: 0,
  timeoutId: null
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Execute and reschedule

state.timeoutId = setTimeout(() => {
  if (!state.active) return;

  func();
  state.count++;
  schedule();
}, waitTime);
Enter fullscreen mode Exit fullscreen mode

Start the first timer

schedule();
intervals.set(id, state);
Enter fullscreen mode Exit fullscreen mode

Return ID

return id;
Enter fullscreen mode Exit fullscreen mode

To clear the interval after it runs

function myClearInterval(id) {
Enter fullscreen mode Exit fullscreen mode

If the interval doesn't exist, do nothing

const state = intervals.get(id);
if (!state) return;
Enter fullscreen mode Exit fullscreen mode

Stop future executions

state.active = false;
Enter fullscreen mode Exit fullscreen mode

Cancel pending timeout

clearTimeout(state.timeoutId);
Enter fullscreen mode Exit fullscreen mode

Remove the interval from tracking

intervals.delete(id);
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

That's all folks!

Top comments (0)