Angular(5)中清除定时器时报错:timeout.close is not a function
解决Angular中clearInterval时报错
timeout.close is not a function的问题 这问题我之前在项目里踩过坑,根源在于Angular默认用Zone.js包装了setInterval这类异步API,导致你拿到的this.inrvl不是原生的定时器ID,而是Zone封装后的对象。当你调用原生clearInterval时,内部逻辑错误地尝试调用这个封装对象的close方法,自然就抛出了timeout.close is not a function的错误。
下面给你两个靠谱的解决方案:
方案1:用NgZone在Angular变更检测外创建定时器
通过NgZone.runOutsideAngular创建定时器,这样定时器就不会被Zone包装,拿到的就是原生的定时器ID,clearInterval就能正常工作:
import { Component, NgZone, OnDestroy } from '@angular/core'; @Component({ selector: 'test', // ...组件其他元数据 }) export class LiveTestGraphComponent implements OnDestroy { private inrvl: number | null = null; constructor(private ngZone: NgZone) {} // 假设你在某个方法/生命周期钩子中启动定时器 startTimer(): void { this.ngZone.runOutsideAngular(() => { this.inrvl = setInterval(() => { loop(+new Date()); // 你的业务逻辑 }, 5); }); } ngOnDestroy(): void { if (this.inrvl) { clearInterval(this.inrvl); this.inrvl = null; // 置空避免后续误操作 } } }
方案2:用DestroyRef自动管理定时器(Angular 14+)
如果你的项目用的是Angular 14及以上版本,推荐用DestroyRef来自动处理销毁逻辑,不用手动判断定时器是否存在,代码更简洁:
import { Component, DestroyRef, inject } from '@angular/core'; @Component({ selector: 'test', // ...组件其他元数据 }) export class LiveTestGraphComponent { private destroyRef = inject(DestroyRef); // 假设你在某个方法/生命周期钩子中启动定时器 startTimer(): void { const intervalId = setInterval(() => { loop(+new Date()); // 你的业务逻辑 }, 5); // 注册销毁时的清除逻辑 this.destroyRef.onDestroy(() => { clearInterval(intervalId); }); } }
最后提个小建议:你设置的定时器间隔是5ms,这个频率非常高,很容易导致浏览器性能卡顿,建议根据实际业务需求调整到合理的间隔(比如100ms以上),避免过度占用资源。
内容的提问来源于stack exchange,提问作者yantrab
相关产品推荐
相关产品推荐

