为什么使用 setTimeout 实现 setInterval?怎么模拟?

Why?

setInterval 的作用是每隔一段指定时间执行一个函数,但是执行不是真的到了时间立即执行,它真正的作用是每隔一段时间将事件加入事件队列中去,只有当 当前的执行栈为空的时候,才能去从事件队列中取出事件执行。所以可能会出现这样的情况,就是当前执行栈执行的时间很长,导致事件队列中累积了多个定时器加入的事件,当执行栈结束的时候,这些事件会依次执行,因此就不能到间隔一段时间执行的效果。
针对 setInterval 的这个缺点,我们可以使用 setTimeout 递归调用来模拟 setInterval,这样我们就确保了只有一个事件结束了,我们才会触发下一个定时器事件,这样解决了 setInterval 的问题。

How?

思路是使用递归函数,不断地去执行 setTimeout 从而达到 setInterval 的效果

function mySetInterval(fn, timeout) {
  function interval() {
    fn();
    setTimeout(interval, timeout);
  }
  //过timeout时间以后,执行setTimeout,调用interval函数
  setTimeout(interval, timeout);
}
//调用mySetInterval
mySetInterval(()=>{
console.log("hello")
,1000);

代码解释:interval函数 在内部递归的时候是先调用一下fn (打印“hello”)再 运行定时器隔timeout以后再调用fn(打印“hello”),这样的话除了第一次之后都是每隔timeout打印hello。
所以我们在外面设置一个setTimeout,使第一次开始调用interval是在timeout后,这样才符合setInterval 每隔timeout执行一次。
还可以加个控制器,控制是否继续执行

function mySetInterval(fn, timeout) {
  // 控制器,控制定时器是否继续执行
  var timer = {
    flag: true,
  };

  // 设置递归函数,模拟定时器执行。
  function interval() {
    if (timer.flag) {
      fn();
      setTimeout(interval, timeout);
    }
  }
  // 启动定时器
  setTimeout(interval, timeout);
  // 返回控制器
  return timer;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值