簡體   English   中英

如何在 RXJS retryWhen 中發出/合並另一個 observable

[英]How to emit/merge another observable inside RXJS retryWhen

我有一個 api 請求的 observable,基本上我在連接失敗/錯誤的事件中添加了retryWhen 這樣做時,我想在請求拋出錯誤時調度另一個操作(不通知用戶系統正在重試..)。

//....
export const saveArticle1 = (action$, state$) =>
  action$.pipe(
    ofType(AUTO_SAVE_ARTICLE_READY),
    withLatestFrom(state$, (a, b) => b),
    switchMap(({
      article,
    }) => {
      const payload = getArticlePayload(article);
      return ajax.patch(`/api/article/${article.id}`, payload, { 'Content-Type': 'application/json' }).pipe(
        flatMap(({ response }) => of({
          type: ARTICLE_AUTO_SAVED,
          value: response,
        })),
        retryWhen(errors =>
          errors.pipe(
            // TODO: I try to concat or merge observable here but no luck
            delay(1000),
            take(60),
          ),
        ),
        catchError((ex) => {
          articleSaveFailureAlert();
          return showErrorNotification('Api Error. Unable to save this article.')(ex);
        }),
      );
    }),
  );

retryWhen調度另一個動作的最佳方法是什么? 還是有另一種方法來實現這一目標?

您可以使用遞歸循環,其停止條件是嘗試次數大於允許的最大嘗試次數。 然后,您可以將“重試”操作的單個 observable 與補丁 observable 連接起來。 如果您編輯代碼段以將maxAttempts更改為小於 5 的數字,您將看到正在發出“失敗”操作。

switchMap在觸發進行持久更改的 API 調用時,您可能需要仔細檢查您對switchMap的使用。 這里有一篇文章詳細解釋了這個問題。

 const {of, operators, throwError, timer, concat} = rxjs; const {switchMap, catchError, flatMap} = operators; const maxAttempts = 60; const patch = (article, attempt) => { if (attempt < 5) return throwError(new Error('server unavailable')); return of(article); }; const action$ = of('patch.id'); const saveArticle1 = action$.pipe( switchMap((article) => { const loop = (attempt) => { return patch(article, attempt).pipe( flatMap((response) => of({ type: 'saved', value: response, })), catchError(error => { if (attempt > maxAttempts) return of({ type: 'failed' }); return timer(1000).pipe( switchMap(() => concat( of({ type: 'retrying' }), loop(attempt + 1) ) ) ); }) ); }; return loop(0); }), ); saveArticle1.subscribe({ next: x => console.log('next', x), error: e => console.error(e), complete: () => console.log('complete') });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.js"></script>

暫無
暫無

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

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