以下代码 clearInterval 为什么不生效?

以下代码 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

回到顶部