一个确认函数已经写了await等待按钮,调用它的函数为什么还会继续执行后面的语句?要回答这个问题,需要分别看被调用的函数在哪里暂停,以及调用者是否也明确等待结果。

Godot 4.5的GDScript文档说明,await用于信号或协程调用时,会立即把控制权交回调用者。信号发出,或者被等待的协程结束后,原函数才从暂停的位置继续。因此,确认函数中的后续代码确实在等待,但不能由此推断调用它的所有代码都会自动一起等待。

文档的示例中,wait_confirmation先输出提示,然后等待按钮的button_up信号,最后继续输出确认信息并返回true。调用者若需要这个返回值来判断接下来做什么,就使用await等待wait_confirmation的结果。文档还特别指出,直接请求协程的返回值而不使用await会出错,不能当成一次已经完成的普通函数调用来取值。

另一种情况是调用者不依赖返回结果。文档给出的okay函数直接调用wait_confirmation,随后打印一条消息;这条消息会在用户按下按钮之前立即输出。两种写法的差异不在确认函数是否含await,而在调用者有没有等待它完成。

检查自己的交互流程时,可以先用自然语言写出依赖关系。例如,“提示出现后可以继续记录界面状态”和“必须得到确认结果后才能决定下一步”是不同要求。然后沿调用关系查看等待点:哪些语句属于确认函数内部,哪些属于外层调用者,以及后者是否真的需要前者的结果。这是根据文档提出的代码阅读方法,并非本轮运行测试。

还有一个容易漏掉的例外:如果await后面的表达式既不是信号,也不是协程,它的值会立即返回,不会因此把控制权交回调用者。文档以返回数字5的普通函数举例,说明加上await这个词本身,并不能凭空制造异步等待。

本文分析的是Godot 4.5官方文档中的控制流程,来源为该版本文档仓库的原始文本。它没有证明某个项目会使用额外线程,也没有提供帧率或界面响应速度的测试结果。遇到“明明写了await仍继续执行”的现象时,先确认等待的是何种对象,以及是哪一层函数在继续,通常比只数代码里出现了几个await更有针对性。

信息来源

本文基于上述公开资料整理,未使用来源页面的图片、视频或嵌入媒体。