繁体   English   中英

不使用 setTimeout/clearTimeout 实现你自己的 setInterval 和 clearInterval 方法

[英]Implement your own setInterval and clearInterval methods without using setTimeout/clearTimeout

我在电话采访中被要求通过编写自己的方法来复制 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;
}
 function setTimeout(func, ms, ...args){
   const start = Date.now();

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

您可以使用伪递归函数和requestAnimationFrame来执行此操作。 基于不带window.setTimeout setTimeout实现,您可以轻松实现新的setInterval ...

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

另一种可能性是,以从例如这里 ,对使用网络工作者

 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 +1。

就像您看到的那样,它是非阻塞的,并且在变量a为10时将停止。

要清除“间隔”,在这种情况下,只需在回调内部return false即可。 显然与clearInterval函数不一样! 这里没有诸如setInterval函数之类的ID。

艰巨的任务,您可以使用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);
});

 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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM