DEV Community

Ravi Ojha
Ravi Ojha

Posted on • Edited on

Javascript: Implement your own setInterval using setTimeout

In one of my recent interview I was asked to implement setInterval.

Here is the question definition:

Let's assume there is no setInterval available to us, but you do have setTimeout and using setTimeOut you have to implement setInterval. It should satisfy these two conditions:

  • It should be able to take callback and delay as parameter.
  • There should be a way to clear the interval.

This is what I was able to come up with (NOTE: This is a brushed up code similar to what I wrote in interview):

function mySetInterval(callback, delay) {
  let clears = [];

  // NOTE: A recursive function which gets called after **delay**
  (function recFun() {
    clears.push(setTimeout(() => {
      callback();
      recFun();
    }, delay));
  }())


  return  () => {
    for (let i = 0; i < clears.length; i++) {
      clearTimeout(clears[i]);
    }
  };
}

// To Test
let count = 1;
let clear = mySetInterval(() => {
  console.log("hello world", count++);
}, 1000);


setTimeout(() => {
  clear();
}, 5000);
Enter fullscreen mode Exit fullscreen mode

There might/will be different ways to solve this, the one thing that I love about the above code is, it gives a practical example of using closures in javascript.

If you have any other way to solve it or you find something wrong with above, please do let me know me in comments.

Approach II: This can handle multiple setInterval

(function(window) {
  let interval = {}
  window.setInterval = function(fun, delay) {
    let rndId = Math.floor(Math.random() * 1000);
    const execute = function() {
      let id = setTimeout(() => {
        fun();
        execute();
      }, delay)

      if (!interval[rndId]) {
        interval[rndId] = []
      }

      interval[rndId].push(id)
      console.log(rndId, interval[rndId])
    }

    execute();

    return rndId;
  }

  window.clearInterval = function(rid) {
    console.log("Rid and Interval", rid, interval)
    while (interval[rid].length > 0) {
      console.log(interval[rid])
      clearTimeout(interval[rid].pop());
    }
  }
}(window))


const pid = setInterval(() => {
  console.log("Hello world");
}, 2000);

console.log("PID", pid)


setTimeout(() => {
  clearInterval(pid)
}, 10000)
Enter fullscreen mode Exit fullscreen mode

-- Thanks, Ravi

Top comments (0)