如何在不使用setTimeout函数的情况下使用setTimeout

问题描述

是否可以使用setTimeout而不使用setTimeout内置函数

我不想使用setIntervalclearIntervalwindow.use。我浏览了多个博客,但所有博客都使用windowsetIntervalclearInterval

例如,下面的代码有效,但是我不想有窗口。

const setTimeouts = [];
function customSetTimeout(cb,interval) {
  const Now = window.performance.Now();
  const index = setTimeouts.length;
  setTimeouts[index] = () => {
    cb();
  };
  setTimeouts[index].active = true;
  const handleMessage = (evt) => {
    if (evt.data === index) {
      if (window.performance.Now() - Now >= interval) {
        window.removeEventListener('message',handleMessage);
        if (setTimeouts[index].active) {
          setTimeouts[index]();
        }
      } else {
        window.postMessage(index,'*');
      }
    }
  };
  window.addEventListener('message',handleMessage);
  window.postMessage(index,'*');
  return index;
}

const setIntervals = [];
function customSetInterval(cb,interval) {
  const intervalId = setIntervals.length;
  setIntervals[intervalId] = function () {
    if (setIntervals[intervalId].active) {
      cb();
      customSetTimeout(setIntervals[intervalId],interval);
    }
  };
  setIntervals[intervalId].active = true;
  customSetTimeout(setIntervals[intervalId],interval);
  return intervalId;
}

function customClearInterval(intervalId) {
  if (setIntervals[intervalId]) {
    setIntervals[intervalId].active = false;
  }
}

console.log("1");
customSetTimeout(function() {
  console.log('3s');
},3000);
console.log("2");

=====================================

替代解决方案: 但是在这里,我又不想使用clearInterval和setInterval

var setMyTimeOut = function(foo,timeOut){
 console.log('inside time out');
    var timer;
  var currentTime = new Date().getTime();
  var blah=()=>{

      if (new Date().getTime() >= currentTime + timeOut) {
      console.log('clear interval if');
        clearInterval(timer);
        foo()
      }
       console.log('clear interval else');
  }
  timer= setInterval(blah,100);
}
console.log("1");
setMyTimeOut(function() {
  console.log('3s');
},3000);
console.log("2");

是否可以实现相同但不使用setInterval和clearInterval?

解决方法

我在这里将requestAnimationFrameperformance.now()一起使用。

它不是超级精确(也没有setTimeout),但是它可以完成工作。

function sleep(delay,cb) {
     function check(time,delay) {
        if(time >= delay) {
           cb("done");
           return;
        }
        time = performance.now();
        requestAnimationFrame(check.bind(null,time,delay))
     }
     check(performance.now(),delay + performance.now());
}



sleep(4000,()=> {
   console.log("sleep done");
})

console.log("i do not block the main thread");

,

您可以使用while循环来检查设置时间和当前时间:

const startTime = new Date().getTime() + 3000;
let currentTime = new Date().getTime();

function customTimeout() {
  while (startTime > currentTime) {
    currentTime = new Date().getTime();
  }
  
  return console.log('3 Seconds')
};

customTimeout();