Эффект NgRx с switchMap и catchError - может ли кто-нибудь объяснить разницу в наблюдаемых рабочих процессах между моим и «правильным» кодом?

Я отправил приведенный ниже фрагмент кода на проверку. Этот эффект должен отправлять успешное действие после вызова запроса или действие при ошибке, если метод службы выдает ошибку, что довольно стандартно.

@Effect()
  fetchData$ = this.actions$.pipe(
      ofType(ActionTypes.FetchData),
      switchMap(() => {
        return this.dataService.fetchData().pipe(
            map((data: IData): StoreAction<IData> =>
                new FetchDataSuccess(data)),
            catchError((error) => of(addErrorValue(error, ErrorCode.FETCH_DATA)))
      )};
  ));

Однако мне дал комментарий внешний разработчик (с которым я не контактировал и поэтому не могу просить разъяснений). Он проинструктировал меня обернуть мой switchMap другим switchMap (например, приведенным ниже кодом), потому что ошибка catch внутри первого switchMap в моем приведенном выше коде «вызовет нарушение эффекта».

@Effect()
  fetchData$ = this.actions$.pipe(
      switchMap((a: StoreAction<IType>) => of(a).pipe(
          ofType(ActionTypes.FetchData),
          switchMap(() => {
            return this.dataService.fetchData().pipe(
                map((data: IData): StoreAction<IData> =>
                    new FetchDataSuccess(data)),
            );
          }),
          catchError((error) => of(addErrorValue(error, ErrorCode.FETCH_DATA)))
      ))
  );

Теперь я прочитал об обнаружении ошибок в эффектах, и я понимаю, что catchErrors необходимо обернуть в switchMap, потому что тогда эффект не сломается, потому что неудачный внутренний (в отличие от внешнего) наблюдаемый будет просто заменен успешным, а наблюдаемый эффект может быть в конечном итоге принудительно переведен в состояние успеха (если я правильно понимаю).

Чего я не понимаю и чего мне не хватает: почему мы оборачиваем switchMap в ДРУГОЙ switchMap? Может кто-нибудь объяснить рабочий процесс этой конкретной наблюдаемой в первом случае по сравнению со вторым?


person Ida Štambuk    schedule 14.11.2019    source источник


Ответы (1)


Это неверно, первый фрагмент (как вы пишете эффект) является правильным.

У вас есть catchError на внутреннем наблюдаемом (this.dataService.fetchData), чего достаточно. Если здесь возникает ошибка, она обрабатывается catchError, и эффект отправляет действие addErrorValue(error, ErrorCode.FETCH_DATA).

Вы можете увидеть тот же шаблон в Пример приложения NgRx

См. https://blog.strongbrew.io/safe-http-calls-with-rxjs/ и https://medium.com/city-pantry/handling-errors-in-ngrx-effects-a95d918490d9 для получения дополнительной информации.

person timdeschryver    schedule 14.11.2019