获取:拒绝承诺与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));