仅当订阅时,如何创建一个每10秒(间隔)更新其值的Observable?

时间:2019-04-01 12:36:25

标签: angular rxjs ngrx

我正在使用RxJS构建角度应用程序。在我的StoreService中,我希望有一个Observable,我的组件可以从中进行订阅。可观察的 public unreadMessagesCount: Observable<number>保留了来自api的未读消息的值。

每10秒钟应进行一次api调用,可观察对象应使用新值进行更新。但是,如果没有组件对此可见对象进行预订,则不应进行轮询。当有人订阅时,应该立即完成。因此,数据从一开始就是最新的。

是否有一种优雅的方法可以使用RxJS构建它?预先感谢!

4 个答案:

答案 0 :(得分:4)

使用timer从N秒开始每N秒创建一个可观察到的发射:

interval$ = timer(1, 10000);

然后您可以声明API调用:

APICall$ = this.http.get('...')

最后,从第二个方法创建一个可观察对象:

pulledData$ = this.interval$.pipe(
  switchMap(() => this.APICall$)
);

现在,除非您订阅它,否则您将没有任何价值。但是一旦订阅,就进行API调用(不过1毫秒后),然后每十秒钟更新一次调用。只记得在销毁组件时取消订阅!

答案 1 :(得分:4)

您可以使用timer,只需定期使用concatMap进行异步调用。如果您希望它在没有初始延迟的情况下发出,则可以使用timer(0, 10000)语法:

import { timer } from 'rxjs';
import { concatMap } from 'rxjs/operators';

timer(0, 10000).pipe(
  concatMap(i => makeHTTPCall(i)),
);

答案 2 :(得分:2)

您可以使用intervalswitchMap创建一个可观察的对象,当您对其进行订阅时,它将开始轮询您的API:

import { interval } from 'rxjs';

const unreadMessagesCount$ = interval(10000).pipe(switchMap(_ => apiCall()));

但是,对于您进行的每个订阅,API调用都会重复。如果您不希望发生这种情况,则必须在所有订户之间共享可观察的源。您可以为此使用multicast

import { interval, Subject } from 'rxjs';
import { multicast} from 'rxjs/operators';

const unreadMessagesCount$ = interval(10000).pipe(
  switchMap(_ => apiCall()),
  multicast(() => new Subject())
);

然后,您只需在可观察对象上调用connect

unreadMessagesCount$.subscribe(value => ...);
unreadMessagesCount$.subscribe(value => ...);

unreadMessagesCount$.connect();
  

请参见this Stackblitz demo

答案 3 :(得分:1)

您可以使用SubjectBehaviorSubjecttimer

import { BehaviorSubject, Observable, timer } from 'rxjs';
import { tap } from 'rxjs/operators';

...
export class YourService {
  value$ = new BehaviorSubject('your initial value');

  constructor() {
    timer(10000).pipe(
      tap(() => this.loadValue())
    ).subscribe();
  }

  loadValue() {
   callYourAPI().subscribe(
     value => this.value$.next(value);
   );
  }
}