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

编程入门 行业动态 更新时间:2024-10-18 10:25:52
本文介绍了如何使用Redux Thunk处理fetch()响应中的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用isomorphic fetch进行API请求,并使用Redux来处理我的应用状态。

I'm making API requests using isomorphic fetch, and using Redux to handle my app's state.

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

I want to handle both internet connection loss errors, and API errors, by firing off Redux actions.

我有以下(正在进行/坏的)代码,但无法找出解雇Redux的正确方法动作(而不仅仅是抛出错误并停止一切):

I have the following (work-in-progress / bad) code, but can't figure out the correct way to fire the Redux actions (rather than just throw an error and stop everything) :

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控制台中,当我通过console.log()(如上所述)登录时,它输出: POST example/post net :: ERR_INTERNET_DISCONNECTED(匿名函数)(发送){返回Promise.all([dispatch({type:PRE_FETCH_RESOURCES_FAIL,errorType:'fatal',message:'Error getting resources',id:_CBUtils2.default.uniqueId()}),dispatch({type:... cb_app_scripts .js?ver = 1.0.0:27976未捕获(承诺)TypeError:req.json不是函数(...)

If I intionally disable the internet connection, in the JS Console, when I log via console.log() (as above), it's outputting this: POST example/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动作(一般错误,一个特定于我们在发生错误时执行的操作) 。

Forgive me if this is entirely wrong, but I don't want to do anything but fire off two Redux Actions when there is an error (a general error, and one specific to the action we were performing when the error occurred).

我正在努力实现的目标是什么?

Is what I'm trying to achieve even possible?

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

It seems that (via my logging to console) the 'then' part of the script is still being executed (as the contents of it are my 'catch' dispatch functions)..

推荐答案

我对几件事感到困惑:

  • 为什么使用 Promise.all 围绕调度两个同步动作?用 {type:PRE_FETCH_RESOURCES_FAIL,...} 调用 dispatch 将不会返回Promise,所以 Promise.all 是不必要的。 Promise.all()仅在您发送的操作自己被写为thunk动作创建者时才有用,这不是这里的情况。
  • return dispatch => ...... 只需要在动作创建者的最开始一次。没有必要在 catch 或然后块中重复此操作 - 实际上,重复它会使内部代码不重复执行完全。这是一种将 dispatch 注入顶级函数的方法,没有必要重复它。
  • 如果你在 catch 之后输入然后,即使在捕获到错误后它也会运行。这不是您想要的行为 - 在错误处理程序之后立即运行成功处理程序是没有意义的。您希望它们是两个独立的代码路径。
  • 次要命名nitpick:您将响应称为 req 。它应该是 res 。
  • Why do you use Promise.all around dispatching two synchronous actions? Calling dispatch with something like {type: PRE_FETCH_RESOURCES_FAIL, ...} won’t return a Promise, so Promise.all is unnecessary. Promise.all() is only useful if the actions you dispatch are themselves written as thunk action creators, which is not the case here.
  • return dispatch => ... is only necessary once at the very beginning of the action creators. There is no need to repeat this in the catch or then blocks—in fact, repeating it makes the inner code not execute at all. This is a way to inject dispatch into your function at the top level, and there is no point to repeating it.
  • If you put then after a catch, it will run even after an error was caught. This is not the behavior your want—it doesn’t make sense to run the success handler right after the error handler. You want them to be two separate code paths.
  • Minor naming nitpick: you are calling the response a "req". It should probably be res.
  • 感觉你的心理错了Redux Thunk如何工作的模型,并试图将不同示例的部分组合在一起,直到它发出咔嗒声。随机缩进也会导致这段代码有点难以理解。

    It feels like you have a wrong mental model of how Redux Thunk works, and are trying to combine parts of different examples together until it clicks. The random indentation also contributes to this code being a little bit hard to understand.

    这将来会很痛苦,所以我建议让一个更完整的心理Redux Thunk做什么的模型,什么 return dispatch => ... 表示Promise如何适应图片。我推荐这个答案为深入Redux Thunk简介。

    This is going to be painful in the future so instead I suggest to get a more complete mental model of what Redux Thunk does, what return dispatch => ... means, and how Promises fit into the picture. I would recommend this answer as an in-depth introduction to Redux Thunk.

    如果我们解决了这些问题,您的代码应该大致相同:

    If we fix those problems, your code should look roughly like this instead:

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

    更多推荐

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

    本文发布于:2023-11-24 20:50:41,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1626768.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:如何使用   错误   Thunk   Redux   fetch

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!