Javascript 在rxjs ajax.map调用中处理异常

Javascript 在rxjs ajax.map调用中处理异常,javascript,reactjs,react-native,rxjs,redux-observable,Javascript,Reactjs,React Native,Rxjs,Redux Observable,我已经根据屏幕上的“”创建了一部史诗 我只是想知道如何将错误处理添加到ajax请求中。我的尝试: const fetchCategoriesEpic = action$ => action$.ofType(FETCH_CATEGORIES) .mergeMap(() => ajax.getJSON(`http://localhost:4000/categories`) .map( response => fetchCa

我已经根据屏幕上的“”创建了一部史诗

我只是想知道如何将错误处理添加到ajax请求中。我的尝试:

const fetchCategoriesEpic = action$ =>
  action$.ofType(FETCH_CATEGORIES)
    .mergeMap(() =>
      ajax.getJSON(`http://localhost:4000/categories`)
        .map(
          response => fetchCategoriesFulfilled(response),
          error => console.log(error)
        )
    )
我正在测试,而我调用的API正在测试错误处理。仍在控制台中获取此信息,应用程序崩溃:

ExceptionsManager.js:71未处理的js异常:ajax错误0

如果那样的话,我应该放弃地图而改为订阅吗

我把它改成这样:

import 'rxjs/add/operator/catch'

const fetchCategoriesEpic = action$ =>
  action$.ofType(FETCH_CATEGORIES)
    .mergeMap(() =>
      ajax.getJSON(`http://localhost:4000/categories`)
        .map(
          response => fetchCategoriesFulfilled(response)
        ).catch( err => console.log(err))
    )
但是得到:

您在需要流的位置提供了未定义的。你可以提供一个 不可观测的、许诺的、阵列的或不可观测的

改为(根据杰伊·菲尔普斯的回答):

得到:

动作必须是普通对象。使用自定义中间件进行异步操作

我做错了什么?

是针对RxJS v4的,而不是v5。v5的文档在这里:源代码在这里

这确实令人困惑,但由于复杂的原因,这是一个不幸的现实


您在需要流的位置提供了未定义的。您可以提供不可观测、承诺、数组或不可观测

出现此错误的原因确实是,您没有根据需要从
catch
操作符使用返回流

redux可观察文档有一个错误处理方法:

所以看起来是这样的:

const fetchCategoriesEpic = action$ =>
  action$.ofType(FETCH_CATEGORIES)
    .mergeMap(() =>
      ajax.getJSON(`http://localhost:4000/categories`)
        .map(
          response => fetchCategoriesFulfilled(response)
        )
        .catch(error => Observable.of({
          type: FETCH_CATEGORIES_REJECTED,
          error
        }))
    )
如果您实际上不想捕获错误并返回另一个可观察对象(如单个错误操作的可观察对象),则可以使用
.do()
仅记录错误:

const fetchCategoriesEpic = action$ =>
  action$.ofType(FETCH_CATEGORIES)
    .mergeMap(() =>
      ajax.getJSON(`http://localhost:4000/categories`)
        .map(
          response => fetchCategoriesFulfilled(response)
        )
        .do({
          error: err => console.log(err)
        })
    )
但是,如果您没有捕捉到错误,它将向上传播源链,终止此Epic,然后继续传播,终止根Epic,使您的应用程序可能无法使用

虽然我不建议这样做,但如果您确实想捕获错误,但只是简单地将其吞下而不进行分派和错误操作,您可以这样做:

const fetchCategoriesEpic = action$ =>
  action$.ofType(FETCH_CATEGORIES)
    .mergeMap(() =>
      ajax.getJSON(`http://localhost:4000/categories`)
        .map(
          response => fetchCategoriesFulfilled(response)
        )
        .catch(error => {
          console.error(error);
          return Observable.empty();
        })
    )
再一次,我强烈反对这种做法——如果有一个错误您非常关心,可以捕获它,您可能应该以某种方式处理它,例如通过调度错误操作并处理它来向用户显示错误


编辑:基于新添加的内容

.catch( err => Observable.of(err.xhr.response))
动作必须是普通对象。使用自定义中间件进行异步操作


事实上,您的epic现在发出的是错误时的XHR响应,而不是redux操作。您的epic只能发出动作。

我可能是瞎子,但我看到的只是:observable/dom cajaxror CAjaxResponse CAjaxTimeoutError IAjaxRequest。描述如何实际使用它的文档在哪里?
.catch( err => Observable.of(err.xhr.response))