-1

I was asked in a phone interview to replicate Javascript's setInterval, clearInterval methods by writing my own. I am not allowed to use setTimeout or clearTimeout.

function setInterval(func, wait){
  var currentTime = Date.now();
  while(currentTime < wait){
   currentTime = Date.now() - currentTime;
  }

  if(currentTime >= wait) { 
    func();
  }
}

function clearInterval(myVar){
  myVar = undeclared;
}
guest
  • 2,185
  • 3
  • 23
  • 46
  • 1
    What else are you allowed to use and what not? It's a pretty broad task. – Bergi Feb 11 '18 at 19:44
  • @Bergi - you can use anything but `setTimeout`, `clearTimeout` – guest Feb 11 '18 at 21:22
  • 1
    those people who are voting to close this question, I will keep re-posting it until I get an answer. The responses below are quite helpful for me and creative in their implementation. – guest Feb 11 '18 at 21:23
  • Anything? What environment are we even talking about? Just [`require('timer')`](https://nodejs.org/api/timers.html) would be absolutely trivial. – Bergi Feb 11 '18 at 21:32
  • Please don't repost it. If the question is off-topic, it will stay so - and "creative" tasks are not exactly making good questions – Bergi Feb 11 '18 at 21:34
  • I will definitely repost @Bergi. I am trying to learn how to do this and this is the reason why I am asking this question. Your definition of creative is different from my definition. I am trying to find out how to implement setInterval without using setTimeout, and if so if you already know the answer, post it. If you don't, then let me learn from other people. It's people like you who make this site so toxic for people like me – guest Feb 11 '18 at 22:54
  • @Bergi You seem to not even able to understand this question. Node.js is a library and a backend framework. I did not say that this is happening a Node.js backend. – guest Feb 11 '18 at 23:06
  • Node.js is a JS environment with its own native APIs, much like the DOM from which the functions below are taken. You did not say anything about where you want the code to work - you only said "JavaScript" - which only signifies how the question is too broad. – Bergi Feb 12 '18 at 09:42
  • @Bergi this is a real question, if you question the legitimacy of the question, then you do not have the answer. This is not a broad question, a true interview question that's asked to be solved within 15 mins. – guest Jun 11 '21 at 00:05
  • It doesn't matter whether it's a real interview question or not, it has unclear requirements and is not suitable for StackOverflow. – Bergi Jun 11 '21 at 00:28
  • @Bergi it's unclear because you don't know the answer. to other people, it's completely clear. No one else complained about the question except you. get out of your head. The requirements to this question are clear to everyone else except you. – guest Jun 11 '21 at 05:46
  • I would know too many answers to this question. From patching the engine over remote procedure calls or busy waiting in a thread to (ab)using really any other asynchronous API that the environment offers in a polling fashion. You already got two totally different answers (neither of which you accepted), and there are countless others. – Bergi Jun 11 '21 at 09:45

3 Answers3

2
 function setTimeout(func, ms, ...args){
   const start = Date.now();

   (function check(){
      if(start + ms >= Date.now()){
         func(...args);
      } else {
         requestAnimationFrame(check);
     }
   })()
}

You might use a pseudorecursive function and requestAnimationFrame to do this. Based on this setTimeout implementation without window.setTimeout you cane easily implement a new setInterval ...

PS: in node you can use process.nectTick instead of requestAnimationFrame

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
2

Another possibility is, taking example from here, the usage of Web Workers:

let mySetInterval = function(callback, timeout) {
    let blob = new Blob([ "self.addEventListener('message', function(e) { \
      let old_date = Date.now(); \
      while (Date.now() - old_date <= " + timeout + ") {}; \
      self.postMessage(true); \
    }, false);" ], { type: "text/javascript" });

    let worker = new Worker(window.URL.createObjectURL(blob));
    worker.addEventListener("message", function(e) {
        if (callback() === false) {
            return
        }
        mySetInterval(callback, timeout)
    }, false);
    worker.postMessage(true);
};

var a = 0;
mySetInterval(() => { if (a >= 10) { return false } else { console.log(a++) } }, 1000)
console.log(45);

Every 1 second it updates the variable a with +1.

Like you see, in this way it is non-blocking and it will stop when the variable a is 10.

To clear the "interval", in this case simply return false inside the callback. Obviously is not the same as the clearInterval function! Here there is not something like an ID such as for the setInterval function.

Lorenzo Pichilli
  • 2,896
  • 1
  • 27
  • 50
1

Hard Task, you can sort of do what setInterval and setTimeout do with requestAnimationFrame ? Not the same, but could do what you want to do.

var time;

function repeatOften() {
  $("<div />").appendTo("body");
  time = requestAnimationFrame(repeatOften);
}

$("#start").on("click", function() {
  time = requestAnimationFrame(repeatOften);
});

$("#stop").on("click", function() {
  cancelAnimationFrame(time);
});
Swink
  • 353
  • 3
  • 26