四时宝库

程序员的知识宝库

使用 RxJS Timer Operator 自动刷新或轮询

有时我们需要在某个时间间隔在我们的组件中自动刷新/轮询。 这可以通过 Timer RxJS 操作符来实现。 但是让我们在没有 RxJS 的情况下这样做,看看我们犯了什么错误,然后我们会进化到最好的解决方案。


export class AutoRefreshTimerComponent implements OnInit,OnDestroy {
 interval:any;
 constructor(private dataService:DataService) {}

  ngOnInit(): void {
    this.getData();
    this.interval = setInterval(()=>{
      this.getData();
    },10000);
  }
  getData(){
   this.dataService.getDataFromAPI().pipe(
      map((response:any)=>console.log(response))
    ).subscribe();
  }
  ngOnDestroy(): void {
    clearInterval(this.interval);
  }
}

我们在 ngOnInit 上调用 getData,因为我们需要在创建组件时第一次调用它。 然后我们使用在 window 对象上可用的 setInterval 方法。

this.interval = setInterval(()=>{
this.getData();
},10000);


此方法返回唯一标识区间的区间 ID。 我们将它存储到组件的间隔中,并在 ngOnDestroy 上清除间隔。

这种方法的问题是我们在每次通话时都订阅但没有取消订阅。

在处理 observables 时,RxJS 操作符是最好的。 因此,让我们利用区间运算符。

export class AutoRefreshTimerComponent implements OnInit, OnDestroy {
  private unsub = new Subject<void>();
  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.getData().subscribe();
    interval(10000)
      .pipe(
        tap((x) => console.log(x)),
        takeUntil(this.unsub),
        switchMap(() => this.getData())
      )
      .subscribe();
  }

  getData() {
    return this.dataService
      .getDataFromAPI()
      .pipe(map((response: any) => console.log(response)));
  }
  
  ngOnDestroy(): void {
    this.unsub.next();
    this.unsub.complete();
  }
}

interval 运算符以毫秒为单位并发出诸如 0,1,2,3 之类的值。在给定的间隔上,我们使用 switchMap 运算符将其映射到我们的 API 调用。 您可以在此处了解有关 switchMap 的所有信息。

上述方法的问题是,我们仍然是单独调用 getData 方法来第一次获取数据。

这可以使用 timer 运算符来解决。

export class AutoRefreshTimerComponent implements OnInit, OnDestroy {
  private unsub = new Subject<void>();
  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    timer(0,15000).pipe(
      tap((x)=>console.log(x)),
      takeUntil(this.unsub),
      switchMap(()=>this.getData())
    ).subscribe();
  }

  getData() {
    return this.dataService
      .getDataFromAPI()
      .pipe(map((response: any) => console.log(response)));
  }

  ngOnDestroy(): void {
    this.unsub.next();
    this.unsub.complete();
  }
}

timer 有两种口味。 timer(initialDelayInMilliSeconds) 采用一个参数,在给定的延迟时间后,它将发出一次值,然后完成。 timer(initialDelayInMilliSeconds,interval) 采用初始延迟和间隔时间。 它将在初始延迟后发出值,然后像区间运算符一样在给定的间隔上发出值。 所以通过这种方式,我们可以通过将 initialDelay 传递为 0 来解决初始调用问题。


我已使用 takeUntil 运算符取消订阅。


我希望这很清楚。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接