我正在使用RxJS构建角度应用程序。在我的StoreService中,我希望有一个Observable,我的组件可以从中进行订阅。可观察的
public unreadMessagesCount: Observable<number>
保留了来自api的未读消息的值。
每10秒钟应进行一次api调用,可观察对象应使用新值进行更新。但是,如果没有组件对此可见对象进行预订,则不应进行轮询。当有人订阅时,应该立即完成。因此,数据从一开始就是最新的。
是否有一种优雅的方法可以使用RxJS构建它?预先感谢!
答案 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)
您可以使用interval和switchMap创建一个可观察的对象,当您对其进行订阅时,它将开始轮询您的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();
答案 3 :(得分:1)
您可以使用Subject
或BehaviorSubject
和timer
:
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);
);
}
}