这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
由发送短信60秒倒计时业务,引出的setTimeout、setInterval问题
首先是了解一下setTimeout、setInterval这两个函数吧
setTimeout和setInteval是window对象上两个主要的定时方法,他们的语法基本相同,但完成功能的却不同。
他们的参数都是,第一个参数是需要执行的函数,第二个是延迟时间,但后面的参数可能大家平时不怎么能用到,也就是第一个执行函数的参数
var intervalID = window.setInterval(cb, 500, '1', '2');
function cb(one, two)
{
console.log(one); // '1'
console.log(two); // '2'
}
复制代码
setTimeout()
方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。
setInterval()
方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。
主要是这样的,我这边有一个业务,就是点击发送短信后,需要有60秒的倒计时
一开始我是这么写的,使用一个递归
setStopTimer() {
const timer = setTimeout(() => {
if (this.second > 1) {
this.second -= 1;
this.setStopTimer();
} else {
this.waiting = false;
this.second = 60;
clearTimeout(timer);
}
}, 1000);
},
复制代码
会上有人提出,我这样写是不是只清除了一个定时器,前面的定时器都没有清除?
我一看这写法的确是只清除了一遍。后来有人推荐写在最上面,清除每一次定时器,但是,这里引发了大家的议论,有一些感觉不用每次都进行清除,有一些觉得每次都需要清除,而且大部分人都有写一个定时器就清除一次的习惯。
然后会上就说这个下来,我在好好研究一下,首先研究一下有没有更好的倒计时实现方式、还有就是对setTimeout清除的问题。这两个问题我一个一个来进行研究吧。
接下来,我在网上进行了一些查询,找到了实现60秒倒计时的一个插件,根据这个插件的源码进行了一些修改,然后使用了promise的方式,这样实现会不会更优雅呢?
this.second = 60;
const promise = new Promise(resolve => {
const setTimer = setInterval(() => {
this.second -= 1;
if (this.second <= 0) {
resolve(setTimer);
}
}, 1000);
});
promise.then((setTimer) => {
clearInterval(setTimer);
// disable为false可再次点击
this.waiting = false;
});
复制代码
接下来就是对于setTimeout和setInterval的清除问题了
经过查询得出,其实setTimeout其实不用每次使用都进行清除,因为它其实只会执行一次,什么时候需要清除呢?这个得根据你的业务来定,比如,你定了一个5秒的定时器,但是你想要在3秒的时候,通过点击一个按钮来截断它这个定时器,这个时候,你就可以进行清除了。
但是,对于setInterval的使用,怎么都得有一个时候对他进行清除,不然他会一致执行下去,不像setTimeout只执行一次
每次调用setTimeout和setInterval后,都会产生一个唯一id,这是一个数字。你可以保存到一个变量里。 你可以使用clearTimeout(id) 或者clearInterval(id) ,来移除这个延时执行。
问题到这里就结束了。