Я использовал альтернативный подход к этой проблеме.
private refresh$ = new Subject<void>();
get items(): Observable<T[]> {
return this.getItems();
}
refresh(): void {
this.refresh$.next();
}
getItems(): void {
const timer$ = timer(0, 30000);
const items$ = this.refresh$.pipe(
startWith(null),
switchMap(_ => timer$),
switchMap(_ => this.getItems()),
shareReplay()
);
return items$;
}
Хотя я не эксперт в rxjs, вот как я думаю, что это работает:
При первой подписке значение null будет отправлено немедленно. Таймер будет подписан и будет выдавать значения каждые 30 секунд, что вызовет HTTP-запрос.
Это будет продолжаться до тех пор, пока не будет вызвано обновление, после чего будет выдано новое значение (неопределенное). Причина, по которой таймер находится в switchMap, заключается в том, чтобы гарантировать, что таймер отменяется (отменяется подписка) каждый раз, когда генерируется наблюдаемое обновление. Таймер будет переподписываться каждый раз, когда это происходит.
Наконец, shareReplay обеспечивает всех подписчиков одинаковой копией данных.
У меня не было особой причины использовать switchMap при выполнении запроса, за исключением того факта, что это самый безопасный оператор отображения в rxjs (или, как говорят в документации).
Надеюсь, это полезно.