【问题标题】:Why line of code isn't executed after awaiting server response为什么等待服务器响应后不执行代码行
【发布时间】:2021-02-05 19:56:59
【问题描述】:

在一个反应​​组件中,我有以下代码:

const handleButton = async () => {
 
  const resp = await updateProject(projectInfo);
  setIsProjectModalVisible(false)

};

updateProject() 是对服务器的 POST 请求,而 setIsProjectModalVisible 是作为 prop 传递的父组件的 setState 函数。

我有一个奇怪的行为:使用前面的代码,Modal 不会被隐藏(setIsProjetModalVisible(false) 不会运行),但是如果我交换两行:

const handleButton = async () => {
 
  setIsProjectModalVisible(false)
  const resp = await updateProject(projectInfo);

};

它会按预期工作并且模态将变得不可见。

经过一番研究,我发现了问题:服务器没有响应 updateProject()。修复该问题后,第二行代码现在将产生预期的行为。

即使问题解决了,我还是想了解一下这种行为:由于服务器没有响应,我可能希望在 await 行中无限等待,但是在调试时,它只会跳过该行并且不会显示错误。这是为什么?谢谢!

【问题讨论】:

  • 我认为从你的代码 sn-p 最好有一个 try catch,所以在这种情况下,如果帖子抛出一个错误,你可以在 catch 时记录,我认为错误正在发生,但来自代码 sn -p 没有什么可以捕捉到它
  • 关闭你的服务器,尝试运行updateProject(projectInfo).then(undefined, (reason) => console.log(reason));而不是你的等待并发布结果,拜托。
  • 您需要检查承诺是成功履行还是未决。因此,严格来说,这可能不是一个错误,而只是您的承诺仍未兑现/未决,从而使您的代码冻结。我认为 catch 可以很好地捕捉实际错误,但对这个特定的异步问题没有帮助

标签: javascript reactjs server async-await httpresponse


【解决方案1】:

当您调用 updateProject 时,它会返回一个 Pending Promise。起初,未决的承诺不会阻止接下来的代码setIsProjectModalVisible(false)

但是,当您将函数声明为async,并将await 标记为您的promise 时,您是在声明以下代码仅应在您的promise 解决时执行。如果 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)
  }
};

【讨论】:

    【解决方案2】:

    根据您的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 仍然会得到一些东西,并且不会阻止代码继续执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      • 2020-03-02
      • 1970-01-01
      • 2020-06-13
      相关资源
      最近更新 更多