我正在使用同构获取发出 API 请求,并使用 Redux 来处理我的应用程序的状态.
I'm making API requests using isomorphic fetch, and using Redux to handle my app's state.
我想通过触发 Redux 操作来处理互联网连接丢失错误和 API 错误.
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(匿名函数)(派遣) {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(...)
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)..
推荐答案我对几件事感到困惑:
感觉就像你对 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() 响应中的错误?
发布评论