在不使用setTimeout / clearTimeout

时间:2018-02-11 19:35:49

标签: javascript

我在电话采访中被要求通过自己编写来复制Javascript的setIntervalclearInterval方法。我不能使用setTimeoutclearTimeout

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

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

function clearInterval(myVar){
  myVar = undeclared;
}

4 个答案:

答案 0 :(得分:1)

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

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

您可以使用伪变形函数和requestAnimationFrame来执行此操作。基于此setTimeout实施而没有window.setTimeout,您可以轻松实施新的setInterval ...

PS:在节点中,您可以使用process.nectTick代替requestAnimationFrame

答案 1 :(得分:1)

另一种可能性是,以here为例,使用Web Workers

&#13;
&#13;
D x N
&#13;
&#13;
&#13;

每1秒更新变量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); +1。

就像你看到的那样,它是非阻塞的,当变量a为10时它会停止。

要清除&#34;时间间隔&#34;,在这种情况下,只需在回调中a。显然与return false功能不一样!这里没有像clearInterval函数那样的ID。

答案 2 :(得分:0)

硬任务,您可以使用requestAnimationFrame执行setInterval和setTimeout的操作吗?不一样,但可以做你想做的事。

var time;

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

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

$("#stop").on("click", function() {
  cancelAnimationFrame(time);
});

答案 3 :(得分:0)

&#13;
&#13;
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++) } }, 10)
console.log(45);
&#13;
&#13;
&#13;