Vue 移动端活动倒计时优化

本文探讨了Vue移动端活动倒计时的优化,指出setInterval存在的精度问题,并介绍了requestAnimationFrame和Web Worker作为优化方案。requestAnimationFrame与浏览器刷新同步,减少误差,而Web Worker实现多线程处理,提高性能。同时,文章通过实际项目场景分析了这两个技术在解决倒计时问题中的应用和限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

通常写倒计时效果,用的是 setInterval,但这会引发一些问题,最常见的问题就是定时器不准。

如果只是普通的动画效果,倒也无所谓,但倒计时这种需要精确到毫秒级别的,就不行了,否则活动都结束了,用户的界面上倒计时还在走,但是又参加不了活动,会被投诉的╮(╯▽╰)╭

一、 知识铺垫

1. setInterval 定时器

先说本文的主角 setInterval,MDN web doc 对其的解释是:

setInterval() 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。

返回一个 intervalID。(可用于清除定时器)

语法: let intervalID = window.setInterval(func, delay[, param1, param2, ...]);
例:

值得注意的是,在 setInterval 里面使用 this 的话,this 指向的是 window 对象,可以通过 call、apply 等方法改变 this 指向。

setTimeout 与 setInterval 类似,只不过延迟 n 毫秒执行函数一次,且不需要手动清除。

至于 setTimeout 和 setInterval 的运行原理,就要牵扯到另一个概念: event loop (事件循环)。

2. 浏览器的 Event Loop

JavaScript 在执行的过程中会产生执行环境,这些执行环境会被顺序的加入到执行栈中,若遇到异步的代码,会被挂起并加入到 task (有多种 task) 队列中。

一旦执行栈为空, event loop 就会从 task 队列中拿出需要执行的代码并放入执行栈中执行。

有了 event loop,使得 JavaScript 具备了异步编程的能力。(但本质上,还是同步行为)

先看一道经典的面试题:

console.log('Script start');

setTimeout(() => {
  console.log('setTimeout');
}, 0);

new Promise((resolve, reject) => {
  console.log('Promise');
  resolve()
}).then(() => {
  console.log('Promise 1');
}).then(() => {
  console.log('Promise 2');
});

console.log('Scritp end'); 

打印顺序为:

  1. “Script start”
  2. “Promise”
  3. “Script end”
  4. “Promise 1”
  5. “Promise 2”
  6. “setTimeout”

至于为什么 setTimeout 设置为 0,却在最后被打印,这就涉及到 event loop 中的微任务和宏任务了。

2.1 宏任务和微任务

不同的任务源会被分配到不同的 task 队列中,任务源可分为微任务( microtask )和宏任务( macrotask ).

在 ES6 中:

  • microtask 称为 Job
  • macrotask 称为 Task

macro-task(Task): 一个 event loop 有一个或者多个 task 队列。task 任务源非常宽泛,比如 ajax 的 onload,click 事件,基本上我们经常绑定的各种事件都是 task 任务源,还有数据库操作(IndexedDB ),需要注意的 是setTimeout、setInterval、setImmediate

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值