项目里面定时器偶然不准的原因以及解决办法:

文章讨论了JavaScript定时器不准的问题,主要原因是被阻塞的任务影响。解决方案包括使用WebWorker在后台线程执行计算密集任务,避免阻塞主线程,以及用requestAnimationFrame替代setTimeout,实现动画循环中的精确延时。
摘要由CSDN通过智能技术生成

定时器不准的原因:        

代码不对导致的定时器不准那肯定不需要过多解释,比较头疼的是因为”被阻塞的任务:如果在setTimeout之前有其他的代码或任务需要执行,并且这些任务的执行时间较长,可能会导致setTimeout的延迟时间被延迟执行或完全被丢弃“这种问题导致的bug在项目里面比较难以复现,但是当大批量用户使用的时候,就会偶然存在定时器不准的问题

解决办法:

1.worker.js

Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。此外,他们可以使用XMLHttpRequest执行 I/O (尽管responseXMLchannel属性总是为空)。一旦创建, 一个worker 可以将消息发送到创建它的JavaScript代码, 通过将消息发布到该代码指定的事件处理程序(反之亦然)。

Web Worker 的作用就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程不会被阻塞或拖慢

// index.js
let count = 0;
//耗时任务
setInterval(function(){
  let i = 0;
  while(i++ < 100000000);
}, 0);

// worker 
let worker = new Worker('./worker.js')
// worker.js
let startTime = new Date().getTime();
let count = 0;
setInterval(function(){
    count++;
    console.log(count + ' --- ' + (new Date().getTime() - (startTime + count * 1000)));
}, 1000);

这种方案体验整体上来说还是比较好的,既能较大程度修正计时器也不影响主进程任务.

2.requestAnimationFrame 动画循环

举例,使用requestAnimationFrame写一个一秒的延时器代替setTimeOut

// 使用requestAnimationFrame代替定时器解决定时器的异常问题
// callback指的是当一秒之后 你需要让这个方法执行的函数 param是这个函数的参数
// 时间长度可以更改 elapsedTime 
function oneSecondTimer (callback, param) {
  let startTime = null
  function tick (timestamp) {
    if (!startTime) {
      startTime = timestamp
    }
    const elapsedTime = timestamp - startTime
    if (elapsedTime >= 1000) {
      callback(param)
      return
    }
    requestAnimationFrame(tick)
  }
  requestAnimationFrame(tick)
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值