Как вывести исключение после исчерпания Rx Js повторных попыток при попытке оператора? - PullRequest
3 голосов
/ 28 марта 2020

Я хочу поймать исключение в подписке, но результат не соответствует ожидаемому.

this.userService.isUsernameValid (username)
      .pipe (
          catchError (err =>
          {
            return throwError (err);
          }),
          retryWhen (errors =>
              errors.pipe (
                  delay (2500),
                  take (4),
                  concatMap (() => throwError ('Network error'))
              )
          )
       )
      .subscribe (
          data =>
          {
            //
          },
          error =>
          {
            console.log (error)
          });

Я бы хотел, чтобы исключение было выдано только в случае неудачи всех попыток.

Приведенный выше код только делает первый запрос, а в случае ошибки выдает исключение (не повторяет запрос).

Если я удалю concatMap, будут сделаны 4 попытки, но я не смогу поймать ошибка в подписке, если ни одна не удалась.

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 29 марта 2020

Вы можете сбросить ошибку самостоятельно при определенных условиях. Например, concatMap передает параметр index в функцию проецирования, которую вы можете использовать вместо take():

throwError("It's broken")
  .pipe(
    retryWhen(errors => errors.pipe(
      concatMap((e, index) => index === 4 ? throwError(e) : of(null)),
    )),
  )
  .subscribe({
    next: x => console.log(x),
    error: e => console.log('obs', e),
  });

Демонстрационная версия: https://stackblitz.com/edit/rxjs-kyr8zp

3 голосов
/ 29 марта 2020

Добавление к решению Мартина:

Приведенный выше код только делает первый запрос и в случае ошибки выдает исключение (не повторяет запрос).

retryWhen(fn) поддерживает внутреннюю подписку на наблюдаемое в результате вызова предоставленной функции fn. Источник retryWhen будет повторно подписан только тогда, когда внутренняя наблюдаемая испускает значение .

В вашем случае, из-за секунды throwError(), он выдаст уведомление об ошибке, так что retryWhen делает в этом случае, чтобы передать уведомление об ошибке целевому подписчику, что в основном означает, что будет вызван обратный вызов ошибки, и весь поток будет отменен Успешно.

Это потому, что когда будет выполнено 4 попытки, внутренняя наблюдаемая будет завершена, что означает, что не будет способа снова выдать значение. Помните, что когда он выдает значение, источник повторно подписывается .

...