Javascript 角度设置超时运行次数太多
我在两个或多个其他组件中实现了日志查看器组件。此日志查看器使用setTimeout创建间隔循环,以从文件中获取数据。我的问题是,由于该组件是在其他组件中导入的,因此计时器会分别为每个组件运行,从而每秒读取多个文件 是否可以避免这种情况,并且无论使用此组件的组件数量如何,都只运行计时器一次 下面是创建setTimeout interval的log viewer组件的代码:Javascript 角度设置超时运行次数太多,javascript,angular,intervals,Javascript,Angular,Intervals,我在两个或多个其他组件中实现了日志查看器组件。此日志查看器使用setTimeout创建间隔循环,以从文件中获取数据。我的问题是,由于该组件是在其他组件中导入的,因此计时器会分别为每个组件运行,从而每秒读取多个文件 是否可以避免这种情况,并且无论使用此组件的组件数量如何,都只运行计时器一次 下面是创建setTimeout interval的log viewer组件的代码: import { Component, ElementRef, OnInit, ViewChild } from '@angu
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { LogsService } from '../../services/logs.service';
import { HelperService } from '../../services/helper.service';
@Component({
selector: 'app-logger',
templateUrl: './logger.component.html',
styleUrls: ['./logger.component.scss']
})
export class LoggerComponent implements OnInit {
@ViewChild('scroller', {static: false}) scroller: ElementRef;
logClassName: string = 'logs shadow close';
logs: string = '';
logTS: number = 0;
logTimer;
scrollTop: number = 0;
constructor(
private logsService: LogsService,
private h: HelperService
){}
ngOnInit(): void {
this.getLogs();
}
ngOnDestroy(): void {
if (this.logTimer) window.clearTimeout(this.logTimer);
}
toggle(type){
switch (type)
{
case 'open': this.logClassName = 'logs shadow open'; break;
case 'close': this.logClassName = 'logs shadow close'; break;
case 'full': this.logClassName = 'logs shadow full'; break;
}
}
getLogs(){
this.logsService.fetch(this.logTS).subscribe(
response => {
this.logs += response.data.join('');
this.logTS = response.ts;
window.setTimeout(() => {
this.scrollTop = this.scroller.nativeElement.scrollHeight;
}, 100);
this.setLogTimer();
},
error => {
this.h.lg('unable to fetch logs', 'error');
this.logs = '<p>Unable to fetch logs</p>';
this.setLogTimer();
}
);
}
setLogTimer(){
if (this.logTimer) window.clearTimeout(this.logTimer);
this.logTimer = window.setTimeout(() => {
this.getLogs();
}, 1000);
}
}
从'@angular/core'导入{Component,ElementRef,OnInit,ViewChild};
从“../../services/logs.service”导入{LogsService};
从“../../services/helper.service”导入{HelperService};
@组成部分({
选择器:“应用程序记录器”,
templateUrl:'./logger.component.html',
样式URL:['./logger.component.scss']
})
导出类LoggerComponent实现OnInit{
@ViewChild('scroller',{static:false})scroller:ElementRef;
logClassName:string='logs shadow close';
日志:字符串=“”;
logTS:number=0;
日志计时器;
scrollTop:number=0;
建造师(
私人日志服务:日志服务,
私人h:助手服务
){}
ngOnInit():void{
这是getLogs();
}
ngOnDestroy():void{
if(this.logTimer)window.clearTimeout(this.logTimer);
}
切换(类型){
开关(类型)
{
大小写“打开”:this.logClassName='logs shadow open';break;
案例“close”:this.logClassName='logs shadow close';break;
大小写“full”:this.logClassName='logs shadow full';break;
}
}
getLogs(){
this.logsService.fetch(this.logTS).subscribe(
响应=>{
this.logs+=response.data.join(“”);
this.logTS=response.ts;
window.setTimeout(()=>{
this.scrollTop=this.scroller.nativeElement.scrollHeight;
}, 100);
这个.setLogTimer();
},
错误=>{
this.h.lg('无法获取日志','错误');
this.logs='无法获取日志;
这个.setLogTimer();
}
);
}
setLogTimer(){
if(this.logTimer)window.clearTimeout(this.logTimer);
this.logTimer=window.setTimeout(()=>{
这是getLogs();
}, 1000);
}
}
要解决此问题,必须使用Angular。您可以在LogsService
中移动setLogTimer()
和logTimer
,问题在于这一点。logTimer与组件实例相关联,每个实例的设置都不一样,而且永远不会取消。解决方案是使用一些共享服务来执行文件读取,就像
@Injectable(provideIn:'root')
export class SomeService{
setLogTimer(){
if (this.logTimer) window.clearTimeout(this.logTimer);
this.logTimer = window.setTimeout(() => {
this.getLogs();
}, 1000);
}
}
然后在组件中使用此服务,如
this.someService.setLogTimer()
另一种方法是使用“rxjs”计时器创建一个可观察对象,并订阅/取消订阅,参见中的示例