Как отменить http-запрос в Reaction-Redx Epic - PullRequest
1 голос
/ 26 сентября 2019

Я хотел бы отменить http-запрос, который я вызываю внутри редукторской эпопеи.Мой http-запрос использует axios, который может предоставить токен отмены ... Но если я создаю токен отмены, где я могу его использовать?

Я превратил свой http-запрос в наблюдаемый с помощью rxjs / from и использую takeUntilот rxjs отписаться от http-запроса ... но действительно ли это "отменяет" мой http-запрос?Как я могу убедиться, что http-запрос действительно отменен?Разве я не должен использовать токен отмены?

const loadApplicationNotesEpic: Epic<Action, Action, RootState> = action$ =>
  action$.pipe(
    filter(isActionOf(actions.getApplicationNotes)),
    map(action => action.payload),
    switchMap(applicationId => {
       // create cancel token here?: 
       // const cancelToken = axios.CancelToken;
       // where to use cancelToken?
      return from(axios.get(apiUrl(`/${applicationId}/notes`))).pipe(
        takeUntil(filterAction(action$, actions.getApplicationNotesCancel)),
        map(notes => actions.getApplicationNotesSuccess(notes, applicationId)),
        catchError(error => {
          console.error(error);
          return of(actions.getApplicationNotesError(error));
        }),
      );
    }),
  );

1 Ответ

0 голосов
/ 27 сентября 2019

Вот пример того, что я думаю, вы можете искать.Я не знаком с axios .Я просто вытащил пример отмены с их веб-сайта.

Я также заменил switchMap на mergeMap, потому что я думаю, что если

..
    filter(isActionOf(actions.getApplicationNotes)),
    map(action => action.payload),
..

произойдет другое действие, то оно отменитподписка на предыдущую наблюдаемую информацию, возвращаемую switchMap без необходимости отмены вызова на axios.get

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

const loadApplicationNotesEpic: Epic<Action, Action, RootState> = action$ =>
  action$.pipe(
    filter(isActionOf(actions.getApplicationNotes)),
    map(action => action.payload),
    mergeMap(applicationId => {
      // create cancel token here?:
      // const cancelToken = axios.CancelToken;
      // where to use cancelToken?

      const promise$ = from(
        axios.get(
          apiUrl(`/${applicationId}/notes`, { cancelToken: source.token })
        )
      ).pipe(
        catchError(error => {
          console.error(error);
          return of(actions.getApplicationNotesError(error));
        })
      );

      const cancelled$ = filterAction(
        action$,
        actions.getApplicationNotesCancel
      ).pipe(mapTo("cancelled"));

      return race(promise$, cancelled$).pipe(
        mergeMap(winner => {
          if (winner === "cancelled") {
            return of(EMPTY).pipe(
                     tap(() => source.cancel('Operation canceled by the user.')),
                     ignoreElements())
          }

          return of(winner).pipe(
            map(notes =>
              actions.getApplicationNotesSuccess(notes, applicationId)
            )
          );
        })
      );
    })
  );
...