首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Redux Thunk处理fetch()响应中的错误?

如何使用Redux Thunk处理fetch()响应中的错误?
EN

Stack Overflow用户
提问于 2016-05-07 01:27:53
回答 2查看 19.4K关注 0票数 19

我正在使用同构fetch发出API请求,并使用Redux来处理我的应用程序的状态。

我想通过触发Redux操作来处理internet连接丢失错误和API错误。

我有以下(工作中/不好的)代码,但我不知道触发Redux操作的正确方法(而不是抛出一个错误并停止一切):

代码语言:javascript
运行
复制
export function createPost(data = {}) {

    return dispatch => {

        dispatch(requestCreatePost(data))

        return fetch(API_URL + data.type, {
            credentials: 'same-origin',
            method: 'post',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'X-WP-Nonce': API.nonce
            },
            body: JSON.stringify(Object.assign({}, data, {status: 'publish'}))
        }).catch((err) => {

            //HANDLE WHEN HTTP ISN'T EVEN WORKING
            return dispatch => Promise.all([
                dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
                dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'})
            ])
        }).then((req) => {

            //HANDLE RESPONSES THAT CONSTITUTE AN ERROR (VIA THEIR HTTP STATUS CODE)
            console.log(req);
            if (!req || req.status >= 400) {
                return dispatch => Promise.all([
                    dispatch({type: FETCH_RESOURCES_FAIL, errorType: 'warning', message:'Error after fetching resources', id: h.uniqueId()}),
                    dispatch({type: CREATE_API_ENTITY_ERROR, errorType: 'warning', id: h.uniqueId(), message: 'Entity error whilst creating'})
                ])
            }
            else {
                return req.json()
            }
        }).then((json) => {
            var returnData = Object.assign({},json,{
                type: data.type
            });
            dispatch(receiveCreatePost(returnData))
        })
    }
}

如果我在JS控制台中禁用了internet连接,当我通过console.log() (如上所述)登录时,它会输出以下内容:POST http://example.com/post net::ERR_INTERNET_DISCONNECTED(anonymous function) (dispatch) { return Promise.all([dispatch({ type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message: 'Error fetching resources', id: _CBUtils2.default.uniqueId() }), dispatch({ type:… cb_app_scripts.js?ver=1.0.0:27976 Uncaught (in promise) TypeError: req.json is not a function(…)

如果这是完全错误的,请原谅我,但我不想做任何事情,只想在出现错误时触发两个Redux操作(一个是一般性错误,另一个是特定于错误发生时我们正在执行的操作)。

我想要实现的目标有可能实现吗?

似乎(通过登录到控制台)脚本的'then‘部分仍在执行(因为它的内容是我的'catch’分派函数)..

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-08 20:04:24

我对几件事感到困惑:

  1. 为什么要使用Promise.all来调度两个同步操作?用{type: PRE_FETCH_RESOURCES_FAIL, ...}之类的东西调用dispatch不会返回Promise,所以Promise.all是不必要的。只有当你发送的动作本身被写成here.
  2. return dispatch => ...动作创建者时,Promise.all()才有用,但事实并非如此,在动作创建者的最开始只需要一次thunk。不需要在catchthen块中重复此操作-事实上,重复此操作会导致内部代码根本不执行。这是一种将dispatch注入到你的函数顶层的方法,没有必要重复它。
  3. 如果你把then放在catch后面,即使在捕获到错误之后,它也会运行。这不是您想要的行为--在错误处理程序之后立即运行成功处理程序是没有意义的。您希望它们是两个独立的代码路径。
  4. 次要命名挑剔:您正在将响应称为“req”。可能应该是res.

感觉你对Redux Thunk的工作原理有一个错误的心理模型,并试图将不同示例的各个部分组合在一起,直到它点击。随机缩进也导致这段代码有点难以理解。

这在未来将是痛苦的,所以我建议获得一个更完整的心理模型,了解Redux Thunk做什么,return dispatch => ...的含义,以及Promises如何与图片相适应。我建议您将此答案作为in-depth introduction to Redux Thunk

如果我们解决了这些问题,你的代码应该大致如下所示:

代码语言:javascript
运行
复制
export function createPost(data = {}) {
  return dispatch => {
    dispatch(requestCreatePost(data));

    return fetch(API_URL + data.type, {
      credentials: 'same-origin',
      method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-WP-Nonce': API.nonce
      },
      body: JSON.stringify(Object.assign({}, data, {status: 'publish'}))
    })
    // Try to parse the response
    .then(response =>
      response.json().then(json => ({
        status: response.status,
        json
      })
    ))
    .then(
      // Both fetching and parsing succeeded!
      ({ status, json }) => {
        if (status >= 400) {
          // Status looks bad
          dispatch({type: FETCH_RESOURCES_FAIL, errorType: 'warning', message:'Error after fetching resources', id: h.uniqueId()}),
          dispatch({type: CREATE_API_ENTITY_ERROR, errorType: 'warning', id: h.uniqueId(), message: 'Entity error whilst creating'})
        } else {
          // Status looks good
          var returnData = Object.assign({}, json, {
              type: data.type
          });
          dispatch(receiveCreatePost(returnData))
        }
      },
      // Either fetching or parsing failed!
      err => {
        dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
        dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'})
      }
    );
  }
}
票数 56
EN

Stack Overflow用户

发布于 2016-05-08 19:44:13

解决方案只是(对于错误日志记录的两个实例)替换:

代码语言:javascript
运行
复制
return dispatch => Promise.all([
    dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
    dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'})
])```

通过以下方式:

代码语言:javascript
运行
复制
return Promise.all([
    dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
    dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'}),
Promise.reject(err)
])
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37078215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档