使用Redux-Observable和RXJS 6获取新的访问令牌和重试操作



我是新来的, rxjs redux-observable ,我正在面临以下问题:

epic 中,我要求一些东西,但是我得到了401,因为我当前的access_token已过期。因此,我需要获得一个新的请求。为此,我使用我存储的refresh_token。我找到了一个似乎与RXJS Verion 5.X一起使用的解决方案,并且我正在尝试使用6版,但我可能缺少某些内容,并且该操作从未完成:

我提出了请求,由于401而失败。然后,我设法要求新的access_token,我将新的access_token收回了,但仅此而已,正在聆听的流回想起来源永远不会执行。p>我试图适应以下方法:rxjs-如何在发出某些内容时捕获和处理错误后如何重试使用RXJS的5.x版本

实现

这是我正在写的史诗:

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()部分,但我想这不是问题所在。无论如何,我也不知道如何使用RXJS6。

实现该部分

在我的redux开发工具中,我看到了此操作:

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)(,但永远不会发射。

如果有人需要知道此问题的答案,事实证明我以错误的方式使用了catchError。如下所述:rxjs可观察物:在其他异步请求之后重试

另外,我必须由RXJS提供的ajax替换Axios(用于HTTP请求(。

工作代码是:

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));
          }
        })
      );
  })
);

最新更新