javascript - 处理 rxjs ajax.map 调用中的异常

标签 javascript reactjs react-native rxjs redux-observable

我根据fetch user demo上的“redux-observable website”创建了一个史诗。 .

我只是想知道如何向 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 Unhandled JS Exception: ajax error 0

如果this is the official docs那么我是否应该摆脱 map 并进行订阅?

我把它改成这样:

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

但是得到了:

You provided undefined where a stream was expected. You can provide an obserable, promise, array or iterable

更改为(根据 Jay Phelps 的回答 here ):

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

得到:

Actions must be plain objects. Use custom middleware for async actions

我做错了什么?

最佳答案

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

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


You provided undefined where a stream was expected. You can provide an obserable, promise, array or 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();
        })
    )

再次,我强烈建议不要这样做——如果有一个错误你足够关心并捕获它,你可能应该以某种方式处理它,例如通过分派(dispatch)错误操作向用户显示错误并进行处理。


编辑:根据您的新添加内容

.catch( err => Observable.of(err.xhr.response))

Actions must be plain objects. Use custom middleware for async actions

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

关于javascript - 处理 rxjs ajax.map 调用中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43551590/

相关文章:

JavaScript - 如何转义 var 中的引号以通过 Json 传递数据

node.js - “npx create-react-app appname” 不工作

xcode - 将字体添加到react-native项目

javascript - 在大量对象中改变单个对象属性的最快方法是什么?

javascript - 将函数传递、接收和使用到子组件中

node.js - react : error TypeError: Network request failed

javascript - 如何使用 Web Audio API 降低麦克风输入的噪音?

javascript - 在 html5 Canvas 中移动

javascript - 创建键值 JavaScript 值

javascript - 如果有条件地检查 react jsx 中的空值 [es6]