0

Redux 文档建议每个 AJAX 请求有 3 个不同的操作。例如,对于登录,它们将是:

  • LOGIN_REUQEST
  • LOGIN_FAILURE
  • LOGIN_SUCCESS

但是我无法捕获所有可能引发的错误fetch。在 redux 文档中,我找到了这个例子:

return fetch(`https://www.reddit.com/r/${subreddit}.json`)
  .then(
    response => response.json(),
    // Do not use catch, because that will also catch
    // any errors in the dispatch and resulting render,
    // causing an loop of 'Unexpected batch number' errors.
    // https://github.com/facebook/react/issues/6895
    error => console.log('An error occured.', error)
  )
  .then(json =>
    // We can dispatch many times!
    // Here, we update the app state with the results of the API call.

    dispatch(receivePosts(subreddit, json))
  )

}

但我发现其中有几个问题:

  1. 它不使用catch,所以它不会在用户端捕获任何AJAX请求问题(例如没有互联网)
  2. 它不处理状态为 != 200 的响应。

我结束了这段代码,但它仍然无法处理案例 #1(因为 React 问题 - 请参阅上面代码中的注释):

 fetch('/api/auth/signin', {...}),
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json, text/plain, */*',
        }
    })
    .then ( response =>
        response.json().then(json => {
            if (response.ok) {
                dispatch(loginSuccess(json))
            } else {
                dispatch(loginFailure(json.errMsg))
            }
        })
     )

您能否给我任何使用 fetch 处理 AJAX 请求的所有可能错误的示例。许多教程和开源项目只是忽略它。

4

2 回答 2

2

您不需要.catch()处理离线错误。的第二个参数.then(),错误回调,将捕获离线(没有互联网连接)错误。

而且,处理不是 200 的响应很简单:

fetch({...})
.then(
  response => {
    if (response.status !== 200) {
      dispatch(loginFailed(response.json()));
      return Promise.reject();
    } else {
      return response.json();
    }
  },
  error => {
    dispatch(loginFailed(error.json()));
    return Promise.reject();
  }
)
.then(json => {
  dispatch(loginSuccess(json));
});
于 2017-09-08T13:52:55.867 回答
1
async function fetchLists(url, token, userName, etag, dataToUpdate) {
var responseJSON;
try {
    let response = await fetch(url,
        {
            method: 'GET',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'X-Access-Token': token,
                'X-Key': userName,
                'If-None-Match': etag
            }
        }
    );
    switch (response.status) {
        case 200:
            var data = await response.json();
            var dataType = getListForUpdate(dataToUpdate);
            responseJSON = {
                action: dataType,
                message: UPDATE_DATA,
                response: response,
                responseJSON: data
            }
            break;
        case 304:
            var dataType = getListUptoDate(dataToUpdate);
            responseJSON = { action: dataType, message: DATA_UPTO_DATE };
            break;
        case 404:
            responseJSON = { message: NOT_FOUND };
            break;
        case 500:
            responseJSON = { message: SERVER_ERROR };
            break;
        case 401:
        case 402:
            responseJSON = { message: INVALID_CREDENTIALS };
            break;
    }
    // console.log(response);
} catch (err) {
    // console.log(err);
    responseJSON = { message: NETWORK_REQUEST_FAILED };
    // console.log(responseJSON);
}

return responseJSON;
}

这个代码结构也许能解决你的问题。我已经记录了所有的响应并留下了网络请求失败的问题。如果您有任何不明白的地方,请发表评论。

希望能帮助到你。

于 2017-09-08T14:30:51.730 回答