获取:拒绝承诺与JSON错误对象
我有一个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 }
// This does not work, since the Promise returned by `json()` is never fulfilled return Promise.reject(resp.json());
那么, resp.json
承诺将会实现,只有Promise.reject
不会等待它,并立即拒绝承诺 。
我会假设你宁愿做以下事情:
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;});
这是一个比较干净的方法,它依赖于response.ok
,并使用底层的JSON数据而不是由.json()
返回的Promise
。
function myFetchWrapper(url) { return fetch(url).then(response => { return response.json().then(json => { return response.ok ? json : Promise.reject(json); }); }); } // This should trigger the .then() with the JSON response, // since the response is an HTTP 200. myFetchWrapper('http://api.openweathermap.org/data/2.5/weather?q=Brooklyn,NY').then(console.log.bind(console)); // This should trigger the .catch() with the JSON response, // since the response is an HTTP 400. myFetchWrapper('https://content.googleapis.com/youtube/v3/search').catch(console.warn.bind(console));