簡體   English   中英

RxJS Observable with Subject,通過計時器和combineLatest進行輪詢不會觸發

[英]RxJS Observable with Subject, polling via timer and combineLatest does not fire

我寫了一個函數來對一個也可以進行分頁的API進行輪詢。 因此,使用Subject Observable完成分頁,並使用計時器方法完成輪詢(我也嘗試使用相同結果的間隔)。

這是我的代碼:

  getItems(pagination: Subject<Pagination>): Observable<ListResult<Item>> {
    let params: URLSearchParams = new URLSearchParams();

    return Observable
      .timer(0, 5000)
      .combineLatest(
        pagination,
        (timer, pagination) => pagination
      )
      .startWith({offset: 0, limit: 3})
      .switchMap(pagination => {
        params.set('skip', pagination.offset.toString());
        params.set('limit', pagination.limit.toString());
        return this.authHttp.get(`${environment.apiBase}/items`, {search: params})
      })
      .map(response => response.json() as ListResult<Item>)
      .catch(this.handleError);
  }

預期的行為是:HTTP請求每5秒觸發一次,當用戶更改頁面時。

這就是:第一個HTTP請求被觸發,但是沒有其他請求被發送到服務器UNTIL分頁被使用。 在第一次使用分頁后,輪詢也開始工作。

這是我第一次使用Observables,所以我很確定我錯過了什么,但我看不出它可能是什么。

我也試過這種方法(也許它在startWith中缺少計時器計數器),但它沒有改變任何東西。

[...]
  .combineLatest(
    pagination
  )
  .startWith([0, {offset: 0, limit: 3}])
[...]

combineLatest()運算符要求所有源Observable都發出至少一個項。

您的演示只生成一個請求,因為您正在使用.startWith() combineLatest()永遠不會發出,因為pagination是一個Subject ,它可能永遠不會發出任何項目。

所以一個選擇是移動.startWith()

.combineLatest(
  pagination.startWith({offset: 0, limit: 3}),
  (timer, pagination) => pagination
)

但也許這對你沒什么幫助,因為你忽略了來自timer()所有項目timer()而你只是使用了pagination 所以也許你可以使用merge()從其中一個源刷新列表。 然后timer()獨立地增加偏移量。

Observable
  .timer(0, 1000)
  .map(i => { return {offset: i*3, limit: 3}})
  .merge(pagination.startWith({offset: 0, limit: 3}))
  .switchMap(pagination => {
    return Observable.of(pagination).delay(200)
  })
  .subscribe(val => console.log(val));

請確保您遵循以下步驟

創建可觀察的數據

你有一個可觀察的可操作數,你正在通過observable.next(value);推送數據observable.next(value);

獲取主題或behourSubject中的數據

在想要獲取數據的地方,您要聲明一個主題類型變量並通過訂閱它來訪問它。

private val: Subject = YourObservable;
private uiValue: string;

val.sunscribe((val) => {
   uiVal = val;
});

現在,您可以在任何位置使用uiVal進行更新。

你可以通過制作console.log來分別測試這兩個部分,以確保一切正常

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM