这是使用 body.json() 并获取状态代码的唯一方法吗?
let status;
return fetch(url)
.then((response => {
status = response.status;
return response.json()
})
.then(response => {
return {
response: response,
status: status
}
});
这不起作用,因为它在响应字段中返回一个承诺:
.then((response)=> {return {response: response.json(), status: response.status}})
您的状态在第二个
then
中不可见。您可以在单个then
中获取这两个属性。
json()
返回一个新的 Promise,因此您需要在该函数结果的 then
内创建对象。如果您从函数返回 Promise,它将被履行并返回履行的结果 - 在我们的例子中是对象。
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(r => r.json().then(data => ({status: r.status, body: data})))
.then(obj => console.log(obj));
.json
方法返回一个承诺,而不是解析的值本身。如果您想在同一个回调中访问响应和解析值,则需要使用如下嵌套函数:
fetch(url).then(response => {
response.json().then(parsedValue => {
// code that can access both here
})
});
或者,您可以在异步函数中使用
await
来消除对回调的需要。
const response = await fetch(url);
const parsedValue = await response.json();
// code that can access both here
当然,您需要通过对 Promise 的
.catch(...)
调用或在 try...catch
函数中使用 async
块来检查错误。您可以创建一个处理 JSON 和错误情况的函数,然后将其重用于所有提取。例如,这样的事情:
function handle(response) {
if (response.ok) {
return response.json().then(parsedValue => {
// the status was ok and the body could be parsed
return { response, parsedValue };
}).catch(err => {
// the status was ok but the body was empty or not JSON
return { response };
});
} else {
return response.json().catch(err => {
// the status was not ok and the body was not JSON
throw new Error(response.statusText);
}).then(parsedValue => {
// the status was not ok and the body was JSON
throw new Error(parsedValue.error); // assuming our API returns an object with an error property
});
}
}
我不认为这是最好的设计模式,但希望这能澄清 fetch API 的工作原理。请注意,如果某些因素阻止请求首先发送,则对
fetch
的调用本身可能会引发错误。
PS:我避免命名任何变量或属性
json
,因为这是文本格式的名称。一旦被解析,它就不再是 JSON。您可能想使用比 parsedValue
更有意义的名称。
使用两个“then”对我来说似乎没有必要。
async/await 可以很轻松地完成工作。
fetch('http://test.com/getData')
.then( async (response) => {
// get json response here
let data = await response.json();
if(data.status === 200){
// Process data here
}else{
// Rest of status codes (400,500,303), can be handled here appropriately
}
})
.catch((err) => {
console.log(err);
})
你尝试过这个吗?
return fetch(url)
.then((r)=> {return {response: r.json(), status: r.status}})
我认为最简洁的方法是使用您需要的部分创建 Promise.all() 。
.then(response => Promise.all([Promise.resolve(response.ok), response.text()]))
可以写得更短为
.then(response => Promise.all([response.ok, response.text()]))
promise 返回一个包含所有结果的数组
.then(data => ({ status: data[0], response: data[1] }))