最近有在写一个移动端项目,验证码需要前端自己实现倒计时,刚好群友问到倒计时实现
群友的问题方案
let time = 0
const start = () => {
time = 60
const flag = setInterval(()=>{
time--
if(time < 0 )clearInterval(flag)
},1000)
}
const start2 = () => {
time = 60
run()
function run(){
time--
if(time < 0){
time = 0
}else{
setTimeout(run,1000)
}
}
}
逻辑十分的语义化
1. 开始设置时间为60
2. 每过1秒执行减1逻辑如果时间减少到0的时候结束
问题
1. 不管 setTimeout 还是 clearInterval 都不能保证刚好1秒之后立即执行,时间非准确的60秒误差不可控
2. 误执行会导致倒计时表现出错
我的方案
const minutes = 1000 * 60 // 一分钟
let oveTime = 0 // 倒计时结束时 间
let flag = null // timeout标记
let time = 0 // 倒计时结束时间
start()
funciton start(){
oveTime = new Date() + minutes // 加法运算 时间戳 + 一分钟 = 结束时间
run()
function run (){
const now = new Date()
time = parseInt((oveTime - now) / 1000) // 结束时间 - 当前时间 的整数秒
if(time < 0){ // 倒计时小于 0 秒 的时候暂停
time = 0
}else{ // 倒计时大于等于0的时候 200 毫秒后继续轮询
setTimeout(run, 200);
}
}
}
群友要求的内卷版本修复了上面的一些bug
const minutes = 1000 * 60; // 一分钟
let oveTime = 0; // 倒计时结束时 间
let flag = null; // timeout标记
let time = 0; // 倒计时结束时间
start();
function start() {
oveTime = +new Date() + minutes; // 加法运算 时间戳 + 一分钟 = 结束时间
run();
function run() {
const now = +new Date();
time = parseInt((oveTime - now) / 1000); // 结束时间 - 当前时间 的整数秒
console.log(time)
if (time < 0) {
// 倒计时小于 0 秒 的时候暂停
time = 0;
} else {
// 倒计时大于等于0的时候 200 毫秒后继续轮询
requestAnimationFrame(run);
}
}
}