jba*_*ter 56 javascript promise es6-promise fetch-api
我有一个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"
}
Run Code Online (Sandbox Code Playgroud)
我想在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
}
Run Code Online (Sandbox Code Playgroud)
Ber*_*rgi 91
Run Code Online (Sandbox Code Playgroud)// 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));
}
})
Run Code Online (Sandbox Code Playgroud)
(或明确写)
return json.then(err => {throw err;});
Run Code Online (Sandbox Code Playgroud)
Jef*_*ick 38
这是一种更简洁的方法,依赖于response.ok并使用底层的JSON数据而不是Promise返回的.json().
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));Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
之所以可行,是因为异步函数总是返回一个promise,一旦有了JSON,我们就可以根据响应状态(使用response.ok)决定如何返回它。
您将以与Jeff的答案相同的方式处理错误,或者可以使用try / catch,甚至处理高阶函数的错误。
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);
}
Run Code Online (Sandbox Code Playgroud)
还值得一读MDN-检查是否成功获取了我们为什么要这样做的信息,本质上来说,获取请求只会拒绝网络错误,获取404并不是网络错误。
| 归档时间: |
|
| 查看次数: |
46785 次 |
| 最近记录: |