Angular interval pipe with a longer task inside

2020-04-18 08:54发布

问题:

I have this code inside my component:

  ngOnInit() {
    ...
    this.counterValue$ = interval(1000).pipe(
      switchMap(() => this.perfService.getCounter(this.counterUrl)),
      map(i => this.updateChart(i)),
    );
    this.counterValue$.subscribe(v => console.log(v));
  }

I wrote this to update a chart every 1s. The problem is that the perfService.getCounter() is taking more than 1s to return. And this causes the following http requests to get canceled:

how to fix this?

回答1:

If you want to update it every 1s while most of the request are taking more than 1s the right operator for you is probably exhaustMap.

Short summary what are the differences between other *map operators in this case:

  • switchMap will cancel the pending request on every emission from interval(1000).

  • mergeMap will make a new request for every emission from interval(1000) so you'll have many pending request at the same time and then overriding their responses as they arrive

  • concatMap will stack the incoming emissions from interval(1000) and then execute them as they complete so if you have a period of very slow responses and then then very fast responses concatMap will be making requests more often then after 1s because it'll first empty it's inner buffer.

  • exhaustMap will make a request and then ignore any subsequent emission from interval(1000) until its inner request completes. No matter how long it takes. Then it'll wait for another emission from the source Observable. So you're guaranteed to have at least 1s delays while not spawning overlapping requests.



回答2:

SwitchMap cancel the event if another new one is coming up, have you tried to use tap operator?



标签: angular rxjs