# 如何解决定时器时间不准的问题

# 存在的场景问题

如果业务本身需求是要求每隔一段时间做一个事情,这时就不可避免的需要用到定时器。 尤其在一些项目排期时间紧,QA在做极限测试的情况下,过多的定时器会带来很鬼畜的问题,即会出现不符合预期的情况。

# 遇到的真实场景

6月在做一个运营推广类的活动,其中有一个动画,点击抽奖后需要快速转动卡片,然后隔几秒后定住,并弹出抽中的卡片,卡片效果是先放大再做翻转。 这一连串的动画都需要用到定时器。果不其然,在QA测试时就遇到了一些问题。 这是业务场景要求的,技术实现方案本身存在问题,那这种情况怎么解决呢?

# 定时器的问题根源

定时器代码: setInterval(fn(), N); 上面这句代码的意思其实是fn()将会在 N 秒之后被推入任务队列。 所以,在 setInterval 被推入任务队列时,如果在它前面有很多任务或者某个任务等待时间较长比如网络请求等,那么这个定时器的执行时间和我们预定它执行的时间可能并不一致。 定时器指定的时间间隔,表示的是何时将定时器的代码添加到消息队列,而不是何时执行代码,即推入任务队列后的任务执行时间不确定。

还有一个问题: 每个 setTimeout 产生的任务会直接 push 到任务队列中;而 setInterval 在每次把任务 push 到任务队列前,都要进行一下判断(看上次的任务是否仍在队列中,如果有则不添加,没有则添加)。 因而我们一般用 setTimeout 模拟 setInterval,来规避掉上面的缺点。

# 解决方案

如果是一些简单的可以用gif图完成的动画推荐用gif图来完成; 如果不能用gif,可以考虑用设计师导出的动画文件,前端通过lottie-web库来加载,效果会比用定时器可控和稳定; 如果以上两种都不行的情况,可以考虑用定时器,但是需要和PM和QA周知可能存在的问题风险,做好降级预案。

# 参考文档

https://segmentfault.com/a/1190000038829248

最后更新时间: 8/27/2021, 4:55:26 PM