我有一个HTTP API,可以在成功和失败时返回JSON数据。
示例失败将如下所示:
~ ◆ http get http://localhost:5000/api/isbn/2266202022
HTTP/1.1 400 BAD REQUEST
Content-Length: 171
Content-Type: application/json
Server: TornadoServer/4.0
{
"message": "There was an issue with at least some of the supplied values.",
"payload": {
"isbn": "Could not find match for ISBN."
},
"type": "validation"
}
我想在JavaScript代码中实现的目标是这样的:
fetch(url)
.then((resp) => {
if (resp.status >= 200 && resp.status < 300) {
return resp.json();
} else {
// This does not work, since the Promise returned by `json()` is never fulfilled
return Promise.reject(resp.json());
}
})
.catch((error) => {
// Do something with the error object
}
答案 0 :(得分:85)
// This does not work, since the Promise returned by `json()` is never fulfilled return Promise.reject(resp.json());
嗯,resp.json
承诺将完成,只有Promise.reject
不会等待它,并立即拒绝带有承诺的 。< / p>
我假设你想要做以下事情:
fetch(url).then((resp) => {
let json = resp.json(); // there's always a body
if (resp.status >= 200 && resp.status < 300) {
return json;
} else {
return json.then(Promise.reject.bind(Promise));
}
})
(或明确写明)
return json.then(err => {throw err;});
答案 1 :(得分:4)
上面Jeff Posnick的解决方案是我最喜欢的方式,但嵌套非常难看。
使用较新的 async / await 语法,我们可以采用更加同步的方式进行,而不会使丑陋的嵌套很快变得混乱。
async function myFetchWrapper(url) {
const response = await fetch(url);
const json = await response.json();
return response.ok ? json : Promise.reject(json);
}
这是有效的,因为an async function always returns a promise,一旦我们有了JSON,我们就可以决定如何根据响应状态返回它(使用response.ok)。
您的错误处理方式与Jeff的答案相同,或者您可以使用try / catch,甚至是error handling higher order function。
const url = 'http://api.openweathermap.org/data/2.5/weather?q=Brooklyn,NY'
// Example with Promises
myFetchWrapper(url)
.then((res) => ...)
.catch((err) => ...);
// Example with try/catch (presuming wrapped in an async function)
try {
const data = await myFetchWrapper(url);
...
} catch (err) {
throw new Error(err.message);
}
另外值得一读MDN - Checking that the fetch was successful为什么我们必须这样做,本质上一个获取请求只拒绝网络错误,获得404不是网络错误。