Fetch API:请求完成后 'await res.json()' 会失败吗?
Fetch API: Can 'await res.json()' fail after a completed request?
获取 API 请求只有在出现网络或服务器错误时才会失败。因此,例如,如果我执行以下代码,假设它没有错误地通过 try
块,我将有一个有效的填充 res
.
try {
const res = await fetch('/createurl', {
method: 'POST',
body: 'testData',
headers: {
'Content-Type': 'application/json'
}
})
if (res.ok) {
alert('Resource created!')
} else {
alert('Error creating resource!')
}
flashResponseToUser(res)
} catch(e) {
alert('A server or network error occurred during the request!')
}
我正在处理 res
以使用 flashResponseToUser(res)
函数向用户显示必要的 error
或 success
消息。由于 res.json()
return 是一个 Promise
,flashResponseToUser
必须是一个异步函数。
const flashResponseToUser = async(res) => {
const jsonRes = await res.json() // Get data from response
console.log(jsonRes)
}
我想知道:
- 为什么
res.json()
return 一个 Promise
因为此时客户端已经收到响应?
res.json()
编辑的 Promise
return 在什么情况下会失败?
flashResponseToUser(res)
中的代码是否也需要包含在 try-catch
块中,因为我正在使用 res.json()
?
Why does res.json() return a Promise since at this point the response has already been received by the client?
fetch
returns 回复 object。这表示已收到响应的 headers,但并不一定意味着已收到整个响应 - 例如,想象一下,当您加载一个巨大的页面时.这与 完全 不同,但您会收到 headers 并且浏览器将开始加载响应,即使还有更多内容需要下载。响应 object 提供 headers 和处理 still-incoming 数据的方法。
Under what conditions would the Promise returned by res.json() fail?
如果响应的格式不正确 JSON,它可能会失败。例如,如果响应的纯文本是 Internal Server Error
,则不是 JSON。这是一个例子:
(async () => {
const response = await fetch('data:,Internal%20Server%20Error');
console.log('got response');
try {
await response.json();
} catch(e) {
console.log('error:', e.message);
}
})();
Does the code within flashResponseToUser(res) also need to be wrapped within a try-catch block since I am using res.json()?
如果您想绝对安全,可以。但是,在大多数情况下,最简单的方法是在 一个地方 捕获,在那里您可以处理错误。您可以在消费者中只处理一次错误,而不是在流程的每一步都处理可能的错误,例如:
const getInfo = async () => {
const res = await fetch('/createurl', {
method: 'POST',
body: 'testData',
headers: {
'Content-Type': 'application/json'
}
})
if (!res.ok) {
throw new Error(res.status);
}
return res.json();
};
getInfo()
.then(flashResponseToUser)
.catch(() => {
alert('A server or network error occurred during the request!')
})
(假设 flashResponseToUser
永远不会抛出,如果提供了预期的 object。如果 flashResponseToUser
无论如何都可能抛出,您可以将 .catch
分离出来区分网络错误和其他运行时错误)
获取 API 请求只有在出现网络或服务器错误时才会失败。因此,例如,如果我执行以下代码,假设它没有错误地通过 try
块,我将有一个有效的填充 res
.
try {
const res = await fetch('/createurl', {
method: 'POST',
body: 'testData',
headers: {
'Content-Type': 'application/json'
}
})
if (res.ok) {
alert('Resource created!')
} else {
alert('Error creating resource!')
}
flashResponseToUser(res)
} catch(e) {
alert('A server or network error occurred during the request!')
}
我正在处理 res
以使用 flashResponseToUser(res)
函数向用户显示必要的 error
或 success
消息。由于 res.json()
return 是一个 Promise
,flashResponseToUser
必须是一个异步函数。
const flashResponseToUser = async(res) => {
const jsonRes = await res.json() // Get data from response
console.log(jsonRes)
}
我想知道:
- 为什么
res.json()
return 一个Promise
因为此时客户端已经收到响应? res.json()
编辑的Promise
return 在什么情况下会失败?flashResponseToUser(res)
中的代码是否也需要包含在try-catch
块中,因为我正在使用res.json()
?
Why does res.json() return a Promise since at this point the response has already been received by the client?
fetch
returns 回复 object。这表示已收到响应的 headers,但并不一定意味着已收到整个响应 - 例如,想象一下,当您加载一个巨大的页面时.这与 完全 不同,但您会收到 headers 并且浏览器将开始加载响应,即使还有更多内容需要下载。响应 object 提供 headers 和处理 still-incoming 数据的方法。
Under what conditions would the Promise returned by res.json() fail?
如果响应的格式不正确 JSON,它可能会失败。例如,如果响应的纯文本是 Internal Server Error
,则不是 JSON。这是一个例子:
(async () => {
const response = await fetch('data:,Internal%20Server%20Error');
console.log('got response');
try {
await response.json();
} catch(e) {
console.log('error:', e.message);
}
})();
Does the code within flashResponseToUser(res) also need to be wrapped within a try-catch block since I am using res.json()?
如果您想绝对安全,可以。但是,在大多数情况下,最简单的方法是在 一个地方 捕获,在那里您可以处理错误。您可以在消费者中只处理一次错误,而不是在流程的每一步都处理可能的错误,例如:
const getInfo = async () => {
const res = await fetch('/createurl', {
method: 'POST',
body: 'testData',
headers: {
'Content-Type': 'application/json'
}
})
if (!res.ok) {
throw new Error(res.status);
}
return res.json();
};
getInfo()
.then(flashResponseToUser)
.catch(() => {
alert('A server or network error occurred during the request!')
})
(假设 flashResponseToUser
永远不会抛出,如果提供了预期的 object。如果 flashResponseToUser
无论如何都可能抛出,您可以将 .catch
分离出来区分网络错误和其他运行时错误)