使用setTimeOut实现setInterval

531 阅读1分钟

为什么要用setTimeOut实现setInterval

在事件循环机制中,异步任务会进入任务队列中执行。像setTimeOut和setInterval这种异步代码,会将里面的回调函数放入WebAPI提供的单独运行空间中,等待延迟时间以后放入任务队列。

不同的是,setTimeOut延迟时间以后直接放入任务队列中,而setInterval会检查任务队列中是否有上次未执行的异步任务,如果没有才会进入任务队列中。

这就导致如果setInterval上次的任务因为其他任务的执行仍在任务队列中,就会导致setInterval没有按照期待的时间间隔执行。

使用setTimeOut实现setInterval

let timer = null;
function interval(fn, wait) {
//内部定义一个递归函数
  let interfun = function () {
      //每次执行将fn放在全局作用域中执行
    fn.call(null);
    //递归调用自己
    timer = setTimeout(interfun,wait);
  }
  //调用递归函数
  timer = setTimeout(interfun,wait);
}
//使用方式
interval(()=>{console.log('aa')},1000)
//清除定时器
window.clearTimeout(timer);