Получить новый токен доступа и повторить действие, используя redux-observable и rxjs 6? - PullRequest
2 голосов
/ 15 мая 2019

Я новичок с rxjs и наблюдаемым редуксом , и я столкнулся со следующей проблемой:

В эпосе я запрашиваю что-то, но я получил 401, потому что мой текущий access_token истек. Поэтому мне нужно получить новый, а затем повторить запрос. Для этого я использую свои сохраненные refresh_token. Я нашел решение, которое, кажется, работает с rxjs verion 5.x, и я пытаюсь реализовать его, используя версию 6, но я, вероятно, что-то упускаю, и операция никогда не завершается:

Я делаю запрос, он отказывает из-за 401. Затем мне удалось запросить новый access_token, я получаю новый access_token обратно, но это все, поток, который слушал, никогда не вызывал источник выполняет.

Я пытался адаптировать это: rxjs - как повторить попытку после перехвата и обработки ошибки с излучением чего-либо который реализован с версией 5.x из rxjs

Вот эпопея, которую я пишу:

export const fetchItems= (action$: any) => action$.pipe(
  ofType(ActionTypes.REQUEST_ITEMS),
  switchMap((action: any) => {
    return request('get', '/items', '', true);
  }),
  map((response: any) => successResponse(response.data)),
  catchError((error: AxiosError, source: any) => {
    if (isError401(error) {
      return action$.pipe(
        ofType(ActionTypes.SUCCESS_REFRESH_TOKEN),
        takeUntil(action$.ofType(ActionTypes.FAILURE_REFRESH_TOKEN)),
        take(1),
        mergeMapTo(source),
        merge(
          of(requestRefreshToken())
        )
      );
    } else {
      return failureResponse(error);
    }
  })
);

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

По ссылке, которую я показал ранее, я не использую часть Observable.defer(), но, думаю, проблема не в этом. В любом случае, я также не знаю, как реализовать эту часть с помощью rxjs 6.

В моих инструментах redux dev я вижу следующие действия:

REQUEST_ITEMS
REQUEST_REFRESH_TOKEN (this is the request of a new access_token passing the current refresh_token)
SUCCESS_REFRESH_TOKEN (this means that I've got a new access_token stored)

после этого я ожидал, что mergeMapTo(source) снова выстрелит REQUEST_ITEMS (и с новым действительным access_token действие может быть завершено, на этот раз попадая в successResponse(response.data)), но оно никогда не будет запущено.

1 Ответ

0 голосов
/ 16 мая 2019

В случае, если кто-то должен знать ответ на эту проблему, оказывается, что я использовал catchError неправильно. Как объяснено здесь: RxJs Observables: запустить retryWhen после еще нескольких асинхронных запросов

Кроме того, мне пришлось заменить axios (который я использовал для http-запроса) на ajax, предоставленный rxjs.

Рабочий код:

export const fetchItems = (action$: any, store: any) => action$.pipe(
  ofType(ActionTypes.REQUEST_ITEMS),
  mergeMap((action: any) => {
    return defer(() => {
        const access_token = store.value.data.auth.access_token;
        const options = {
          headers: {
            Authorization: `Bearer ${access_token}`,
          },
          url: '/items',
        };
        return ajax(options);
      })
      .pipe(
        map((response: any) => successItems(response.response)),
        catchError((error: any, source: any) => {
          if (isError401(error)) {
            return action$.pipe(
              ofType(ActionTypes.SUCCESS_REFRESH_TOKEN),
              takeUntil(action$.ofType(ActionTypes.FAILURE_REFRESH_TOKEN)),
              take(1),
              mergeMapTo(source),
              merge(
                of(requestRefreshToken())
              ),
            );
          } else {
            return of(failureItems(error));
          }
        })
      );
  })
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...