簡體   English   中英

在 rxjs observable 訂閱開始時進行 Angular 偵聽?

[英]Angular listen on subscription start of rxjs observable?

有沒有辦法檢測管道內可觀察的 rxjs 的訂閱開始?

我想在訂閱 http observable(在響應完成時銷毀)時觸發加載指示器。

或者我是否必須為此操作創建一個可觀察的包裝器?

這取決於您使用的 RxJS 版本。 使用 RxJS < 7.3 你可以使用defer()

defer(() => {
  loadingFlag = true;
  return this.http.doyourrequest().pipe(
    finalize(() => loadingFlag = false),
  );
});

由於 RxJS >= 7.3 你可以為tap()使用新的事件處理程序:

this.http.doyourrequest().pipe(
  tap({
    subscribe: () => loadingFlag = true,
    finalize: () => loadingFlag = false,
  }),
);

由於對 http observable 的每個訂閱都會導致新的 http 調用,因此在管道外設置此類標志是安全的,至少我是這樣做的。

getSomeData(){
  loadingFlag=true;
  return this.http.doyourrequest().pipe(finalize(()=>loadingFlag=false));
}

如果你真的想通過子計數(由於 http obs 的 finalizztion,每次請求后總是下降到 0)檢查 refCount() 和 share() 運算符的實現,它們在內部對訂閱者進行計數

不要在您的流中設置一些指標作為副作用,而是嘗試創建一個返回請求狀態的 observable。

readonly makeRequestSubject = new Subject<RequestParams>();
readonly request$ = makeRequestSubject.pipe(
  switchMap(params => this.doRequest(params).pipe(
    map(result => ({ params, result,  state: 'complete' })),
    catchError(error => ({ error, params, state: 'error' }))
    startWith({ params, state: 'loading' })
  ),
  startWith({ state: 'notstarted' }),
  shareReplay(1)
);
readonly isLoading$ = this.request.pipe(map(x => x === 'loading'), distinctUntilChanged());
readonly results$ = this.request.pipe(map(x => x === 'complete' ? x.results : []));
  1. 可以從一個方法返回一個 observable 並像一個超重的承諾一樣使用它,或者你可以有一個包含流的字段,所有依賴者都可以在他們想要的時候訂閱和取消訂閱它。 每次您需要發出新請求時,都會調用makeRequestSubject上的next()
  2. 外部startWith應該首先發射。 這是可選的,但在某些 ui 場景中可能很有用,例如如果沒有發出請求,則顯示帶有說明的消息。
  3. 該請求是在switchMap 中發起的,因此如果先前的調用尚未完成,則連續調用將中斷它們。
  4. 除非請求是即時的,否則內部startWith運算符將首先發出。
  5. catchError說明了除了設置加載指示器之外的另一個典型用例。
  6. 您可以直接訂閱request$ ,也可以使用isLoading$和 results$**。 我通常會盡量避免創建額外的 observable,只需確保主流中組件上的模型與我的 ui 綁定匹配。
  7. 參數只是被包含在內,因為它們可能在 ui 中有用。

暫無
暫無

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

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