以下代码 clearInterval 为什么不生效?
class Interval { constructor() {
this.timeMap = {};
this.id = 0;
}
setInterval = (cb, time) => {
this.id++;
let fn = () => {
this.timeMap[this.id] = setTimeout(fn, time);
cb();
};
this.timeMap[this.id] = setTimeout(fn, time);
return this.id; // 返回 this.id
};
//改成这样就好了 但是不知道原理
_setInterval = (cb, time) => {
let timerId = this.id++;
let fn = () => {
this.timeMap[timerId] = setTimeout(fn, time);
cb();
};
this.timeMap[timerId] = setTimeout(fn, time);
return timerId; // 返回timeId
};
clearInterval = (id) => {
clearTimeout(this.timeMap[id]); // 通过timeMap[id]获取真正的id
delete this.timeMap[id];
};
}
let s = new Interval();
// 第一个定时器
let timer = s.setInterval(() => {
console.log('timer', timer);
}, 1000);
// 第二个定时器
let timer1 = s.setInterval(() => {
console.log('timer1', timer1);
}, 1000);
// 第三个定时器
let timer2 = s.setInterval(() => {
console.log('timer2', timer2);
}, 1000);
setTimeout(() => {
s.clearInterval(timer2); // !!!这里为什么只能清除最后一个定时器, 我传递 timer timer1 就无效
}, 2500);
参考 掘金
https://juejin.cn/post/684490...
刚开始认为 这个 this.id是 非引用类型,应该不会影响~
然后进一步想到 闭包 作用域的定义之类的,但是还是没有想明白.请各位看官 大佬 解读一番!
回答:
clearTimeout和setTimeout的实际顺序你稍微打印一下,你就不觉得你的cb时机不太对吗
回答:
this.timeMap[this.id] = setTimeout(fn, time);
每次执行setTimeout
的时候timeId
都是会发生变化的,你写的timer
只是第一次执行setTimeout
时候的timeId
,当然不能用它来清除后面的timeOut
了。
ps:链接是掘金,为什么说参考知乎
回答:
生效了,cb()
之后你又setTimeout了一次,所以看起来像是没生效,自己调试一下就知道了。
这样改一下就对了,不过没啥意思,代码写的太没思路了,知乎那个也是
class Interval { constructor() {
this.timeMap = {};
this.id = 0;
}
setInterval = (cb, time) => {
let fn = () => {
if (!cb())
this.timeMap[this.id] = setTimeout(fn, time);
else
this.clearInterval(this.id);
};
this.timeMap[this.id] = setTimeout(fn, time);
return this.id; // 返回timeId
};
clearInterval = (id) => {
clearTimeout(this.timeMap[id]); // 通过timeMap[id]获取真正的id
delete this.timeMap[this.id];
};
}
let s = new Interval(),
i = 0,
timer = null;
timer = s.setInterval(() => {
console.log('timer', timer);
return i++ === 2;
}, 1000);
以下代码足够了,为啥搞那么复杂
let handle;let i = 0;
const foo = () => {
handle = setTimeout(() => {
console.log(i);
i ++;
foo();
}, 1000);
}
foo();
setTimeout(() => {
clearTimeout(handle);
}, 3000)
或者这样直接把清除的方法返回来
const vsetInterval = (cb, time) => { let handle;
const foo = () => {
handle = setTimeout(() => {
cb();
foo();
}, time);
}
foo();
return () => clearTimeout(handle);
}
const vclearInterval = vsetInterval(()=>console.log((new Date).valueOf()), 500);
setTimeout(vclearInterval, 5000);
回答:
把自己绕进去了
let fn = () => { // 这里打印 this.id 已经不对了 所以需要独立一个变量出来
console.log('id', this.id);
this.timeMap[this.id] = setTimeout(fn, time);
cb();
};
以上是 以下代码 clearInterval 为什么不生效? 的全部内容, 来源链接: utcz.com/p/936619.html