2

我根据redux-observable 网站上的“获取用户演示”创建了一个史诗。

我只是想知道如何向 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))
    )

但得到:

您在预期流的位置提供了 undefined 。你可以提供一个 oberable、promise、array 或 iterable

更改为(根据杰伊菲尔普斯在这里的回答):

const fetchCategoriesEpic = action$ =>
  action$.ofType(FETCH_CATEGORIES)
    .mergeMap(() =>
      ajax.getJSON(`http://localhost:4000/categories`)
        .map(response => fetchCategoriesFulfilled(response))
        .catch( err => Observable.of(err.xhr.response))
    )

得到:

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

我究竟做错了什么?

4

1 回答 1

3

https://github.com/Reactive-Extensions/RxJS-DOM适用于 RxJS v4,而不是 v5。v5 的文档在这里:http ://reactivex.io/rxjs/和源代码在这里https://github.com/ReactiveX/rxjs

这绝对令人困惑,但由于复杂的原因,这是不幸的现实。


您在预期流的位置提供了 undefined 。你可以提供一个 oberable、promise、array 或 iterable

您收到此错误的原因确实是,您没有catch根据需要从运营商使用中返回流。

redux-observable 文档在这里有一个错误处理方法:https ://redux-observable.js.org/docs/recipes/ErrorHandling.html

所以它看起来像这样:

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

如果您实际上不想捕获错误并返回另一个 Observable(例如单个错误操作的 Observable),那么您可以使用.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))

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

实际上,您的史诗现在正在发出 XHR 错误响应,而不是 redux 操作。你的史诗只能发出动作。

于 2017-04-21T20:48:01.010 回答