为什么在等待服务器响应后不执行代码行
Why line of code isn't executed after awaiting server response
在一个反应组件中,我有以下代码:
const handleButton = async () => {
const resp = await updateProject(projectInfo);
setIsProjectModalVisible(false)
};
updateProject() 是对服务器的 POST 请求,而 setIsProjectModalVisible 是来自父组件的 setState 函数,作为 prop 传递。
我有一个奇怪的行为:使用前面的代码,Modal 不会被隐藏(setIsProjetModalVisible(false) 不会 运行),但是如果我交换这两行:
const handleButton = async () => {
setIsProjectModalVisible(false)
const resp = await updateProject(projectInfo);
};
它将按预期工作,模态框将变得不可见。
经过一些研究,我确定了问题所在:服务器没有响应 updateProject()。解决这个问题,第二行代码现在会产生预期的行为。
即使问题已解决,我还是想了解这种行为:由于服务器没有响应,我可能会在 await 行中等待无限期,但在调试时,它会跳过该行并且没有显示错误。这是为什么?谢谢!
当您调用 updateProject
时,它 returns 是一个 Pending Promise。起初,待处理的承诺不会阻止下一个代码 setIsProjectModalVisible(false)
.
但是当您将函数声明为 async
并在您的承诺中标记 await
时,您是在声明以下代码仅应在您的承诺解决时执行。如果 promise 挂起,您的代码将被阻止,直到 promise 解决。
promise 也可能会拒绝(您收到服务器超时错误或其他错误),这会引发错误,但您的代码不会被执行。你的应用程序会崩溃,除非你将你的承诺包装在 try/catch 块中(推荐),你可以在 catch 块中正确处理错误。
const handleButton = async () => {
try {
const resp = await updateProject(projectInfo);
// if it rejects following code doesn't execute. jumps to catch block
setIsProjectModalVisible(false)
} catch (error) {
// handle error here
console.log(error)
}
};
根据您的 updateProject
的编写方式,当其中的 POST 请求以某种方式失败时,它可能无法解决(即您没有发现错误),因此您的const resp = await updateProject(projectInfo);
从来没有真正得到任何回报。当然,这会导致这部分 setIsProjectModalVisible(false)
永远无法到达。因此,您的模态不会消失。
所以这应该可以解释这种行为。至于修复它,好吧,只要捕获错误并仍然解决该功能即可。所以这样的事情会起作用:
const updateProject = (project_data) => {
return axios.post('url', project_data)
.catch(e => {
console.log(e);
return "Error occurred";
})
}
这样即使您的 post 请求炸弹,您的 await 仍然会返回一些东西并且不会阻止代码继续执行。
在一个反应组件中,我有以下代码:
const handleButton = async () => {
const resp = await updateProject(projectInfo);
setIsProjectModalVisible(false)
};
updateProject() 是对服务器的 POST 请求,而 setIsProjectModalVisible 是来自父组件的 setState 函数,作为 prop 传递。
我有一个奇怪的行为:使用前面的代码,Modal 不会被隐藏(setIsProjetModalVisible(false) 不会 运行),但是如果我交换这两行:
const handleButton = async () => {
setIsProjectModalVisible(false)
const resp = await updateProject(projectInfo);
};
它将按预期工作,模态框将变得不可见。
经过一些研究,我确定了问题所在:服务器没有响应 updateProject()。解决这个问题,第二行代码现在会产生预期的行为。
即使问题已解决,我还是想了解这种行为:由于服务器没有响应,我可能会在 await 行中等待无限期,但在调试时,它会跳过该行并且没有显示错误。这是为什么?谢谢!
当您调用 updateProject
时,它 returns 是一个 Pending Promise。起初,待处理的承诺不会阻止下一个代码 setIsProjectModalVisible(false)
.
但是当您将函数声明为 async
并在您的承诺中标记 await
时,您是在声明以下代码仅应在您的承诺解决时执行。如果 promise 挂起,您的代码将被阻止,直到 promise 解决。
promise 也可能会拒绝(您收到服务器超时错误或其他错误),这会引发错误,但您的代码不会被执行。你的应用程序会崩溃,除非你将你的承诺包装在 try/catch 块中(推荐),你可以在 catch 块中正确处理错误。
const handleButton = async () => {
try {
const resp = await updateProject(projectInfo);
// if it rejects following code doesn't execute. jumps to catch block
setIsProjectModalVisible(false)
} catch (error) {
// handle error here
console.log(error)
}
};
根据您的 updateProject
的编写方式,当其中的 POST 请求以某种方式失败时,它可能无法解决(即您没有发现错误),因此您的const resp = await updateProject(projectInfo);
从来没有真正得到任何回报。当然,这会导致这部分 setIsProjectModalVisible(false)
永远无法到达。因此,您的模态不会消失。
所以这应该可以解释这种行为。至于修复它,好吧,只要捕获错误并仍然解决该功能即可。所以这样的事情会起作用:
const updateProject = (project_data) => {
return axios.post('url', project_data)
.catch(e => {
console.log(e);
return "Error occurred";
})
}
这样即使您的 post 请求炸弹,您的 await 仍然会返回一些东西并且不会阻止代码继续执行。