【问题标题】:How can I escape a catch chain early with rxjs?如何使用 rxjs 尽早逃脱捕获链?
【发布时间】:2017-06-15 16:21:15
【问题描述】:

我制作了一个包装器,用于使用身份验证标头访问“rxjs/observable/dom/ajax”函数。那部分没问题。

export const authjax = {
  create: urlOrRequest => ajax(typeof urlOrRequest === 'string'
    ? {url: urlOrRequest, headers: authHeader()} : _.merge({}, urlOrRequest, {headers: authHeader()})
  ),
  get: (url, headers = {}) => ajax.get(url, {...headers, ...authHeader()}),
  post: (url, body = {}, headers = {}) => ajax.post(url, body, {...headers, ...authHeader()}),
  put: (url, body = {}, headers = {}) => ajax.put(url, body, {...headers, ...authHeader()}),
  patch: (url, body = {}, headers = {}) => ajax.patch(url, body, {...headers, ...authHeader()}),
  getJSON: (url, headers = {}) => ajax.getJSON(url, {...headers, ...authHeader()})
};

所以,它被用来代替 ajax。这是一个在史诗中使用它的例子。

export const getBatchesEpic = (action$, store) =>
  action$.ofType(actions.GET_BATCHES)
    .switchMap(action => {
      const {paginate, refresh} = action;
      const paginatorNext = _.get(store.getState(), 'manager.paginator.batches.next');
      const usePaginatorNext = paginatorNext && paginate && !refresh;
      return authjax.get(usePaginatorNext ? paginatorNext : `${API_URL}/batches/`)
        .concatMap(({response}) => {
          const incompleteBatches = response.results.filter(batch => !batch.completed);
          const checkBatchActions = incompleteBatches.map(batch => checkBatch(batch.id));
          return [
            {type: actions.BATCHES_RECEIVED, data: response, next: response.next, paginate},
            ...checkBatchActions
          ];
        })
        .catch(error => Observable.of({type: actions.GET_BATCHES_ERROR, error})
      );
    });

现在,我正处于尝试仅使用 authjax.get 方法通过简单测试的第一阶段。我希望来自服务器的 401 响应被 authjax 捕获,并让 authjax 返回注销操作,以及取消任何以下链接方法。

这是我对authjax.get 的最新尝试。它适用于成功的 ajax 响应和非 401 ajax 响应。当它到达 401 时,它不会返回任何内容,甚至是注销操作。

export const authjax = {
  create: urlOrRequest => ajax(typeof urlOrRequest === 'string'
    ? {url: urlOrRequest, headers: authHeader()} : _.merge({}, urlOrRequest, {headers: authHeader()})
  ),
  get: (url, headers = {}) => {
    const call = ajax.get(url, {...headers, ...authHeader()});

    return call.catch(error => {
      if (_.get(error, 'status') === 401) {
        console.log('401!!!', Observable.of({type: actions.LOGOUT}));
        return Observable.of({type: actions.LOGOUT}).ignoreElements();
      }
      return call;
    });

  },
  post: (url, body = {}, headers = {}) => ajax.post(url, body, {...headers, ...authHeader()}),
  put: (url, body = {}, headers = {}) => ajax.put(url, body, {...headers, ...authHeader()}),
  patch: (url, body = {}, headers = {}) => ajax.patch(url, body, {...headers, ...authHeader()}),
  getJSON: (url, headers = {}) => ajax.getJSON(url, {...headers, ...authHeader()})
};

我正在阅读 rxjs 文档,但发现假设您永远不需要切换或取消流中的流。我知道可能有一些选项可以让我在 Epic 本身中处理更多内容,但我希望 authjax 能够处理自己的身份验证问题,以便我可以将其用作使用相同身份验证的多个应用程序的导入。

【问题讨论】:

  • 我不得不做同样的几次 - 根据 concatMap 内部的结果取消所有等待的 concatMap 请求。我最近回答了一个类似的问题:stackoverflow.com/questions/44496395/…
  • zip 对我不起作用,因为我必须在返回之前完成从 authjax 返回的任何内容,因此我无法将以下链式方法添加到 zip 中。我在返回的 observable 上尝试了 .ignoreElements() ,但它也忽略了我返回的第一个元素,它只拾取链中与错误相关的事件。如果我抛出一个错误然后链接到 .ignoreElements,我的 catch 语句稍后会触发。我可能试图让 rxjs 做一些不应该做的事情。

标签: javascript error-handling rxjs reactive-programming redux-observable


【解决方案1】:

这是我目前想出的答案。

export const wrapAjax = ({method, args = {}}) => {
  const headers = {...args.headers || {}, ...authHeader()};

  const call = method
    ? ajax[method](..._.values(_.omit(args, ['headers'])), headers)
    : ajax(_.merge({}, args, {headers}));

  return call.catch(error => {
    if (_.get(error, 'status') === 401) {
      return Observable.throw({...error, action: {type: actions.AUTH_401, error}}).ignoreElements();
    }
    return call;
  });
};

如果状态为 401,它会停止任何链式方法,并命中任何后面的 catch 语句。遗憾的是,史诗中的 catch 语句必须调度返回的动作属性。没有被激怒,但这就是我现在继续前进的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2016-02-11
    相关资源
    最近更新 更多