问题描述:
使用setTimeout动态的修改setInterval的周期依次为a,a+b,a+2b,a+3b,...,a+nb。并在指定时间后停止这个周期函数。
问题关键点:
(1)动态的修改setInterval的周期
(2)在指定时间后停止这个周期函数
问题实现思路:
针对第一个点,动态的修改setInterval的周期,直接在原始的interval上修改是不会生效的,也就是下面这种写法:
let count = 0;
setInterval(() => {
console.log(new Date());
}, 1000 + 1000 * count++);
打印结果如下:
如果想要生效,只能通过先清空上一次的interval,然后赋予新的interval,才能达到修改周期的目的。代码如下:
let count = 0;
let timer;
// 声明一个周期函数
timer = setInterval(() => {
// 执行具体方法
test();
// 清除周期函数
clearInterval(timer);
// 修改周期大小
count++;
// 重新声明一个周期函数
timer = setInterval(() => {
// 执行具体方法
test();
// 清除周期函数
clearInterval(timer);
// 修改周期大小
count++;
...
}, 1000 + count * 1000);
}, 1000);
function test(){
console.log(new Date());
}
细心的同学应该发现了,这是一个递归的过程。
上述代码中重复的部分就是我们要递归的内容,我们把公共部分抽出来,然后把这个函数变成一个递归函数:
let count = 0;
function varyInterval() {
let delay = 1000 + 1000 * count++;
let timer = setInterval(() => {
test();
clearInterval(timer);
varyInterval();
}, delay);
}
varyInterval();
function test(){
console.log(new Date());
}
运行结果如下:
可以发现,我们想要动态修改周期的目的已经达到了~
细心的同学可以发现,这里的setInterval是可以用setTimeout来替换的。
实际上,这里的setInterval起的作用和setTimeout一样。
原因是,我们每到一个周期结束时就会使用clearInterval()来清除这个周期函数,然后重新生成一个新的周期函数,赋予它新的周期,从而实现动态修改周期函数的周期的目的~
因此,我们可以把这里的setInterval换成setTimeout:
let count = 0;
function varyInterval() {
let delay = 1000 + 1000 * count++;
let timer = setTimeout(() => {
test();
clearTimeout(timer);
varyInterval();
}, delay);
}
varyInterval();
function test(){
console.log(new Date());
}
它们的执行结果是一样滴~
至此,我们使用setTimeout来动态修改周期函数的周期的目的就达到啦~
接下来,我们来实现第二点:在指定时间后结束这个周期函数。
第一个点里实现的周期函数,如果没有外力代码来强行阻止的话,这个周期函数会一直执行下去。
如果我们想要在指定时间后结束它的话,再加一个定时器就好啦~
这里的核心点只有一个:那就是多个定时器之间可以并行,不会冲突。
因此我们再来完善一下代码:
let count = 0;
let stop = false;
function test() {
console.log(new Date());
}
// 多个定时器setTimeout之间是并行的,每个定时器都有自己的编号
let timer = setTimeout(() => {
stop = true;
clearTimeout(timer);
},5000);
function varyInterval() {
if (stop === true) {
return;
}
let delay = 1000 + 1000 * count++;
let timer = setTimeout(() => {
test();
clearTimeout(timer);
varyInterval();
}, delay);
}
varyInterval();
控制台输出一下:
可以发现,我们在指定时间之后中断周期函数的目的就达到啦~