全局调用异步函数时出错:“等待仅在异步函数和模块的顶层主体中有效”?
Posted
技术标签:
【中文标题】全局调用异步函数时出错:“等待仅在异步函数和模块的顶层主体中有效”?【英文标题】:Error in global call to async function: "await is only valid in async functions and the top level bodies of modules"? 【发布时间】:2021-08-13 17:35:15 【问题描述】:在我开始之前,我承认有几个关于 SO 的问题听起来可能与我的标题相似相似,但是,我阅读的所有问题都更多 比我的代码复杂,而且解释似乎与我的情况无关。
谁能帮我理解我的代码(下面的sn-p)中发生了什么导致这个错误:
未捕获的语法错误:await 仅在异步函数中有效,并且 模块的顶层主体。
据我所见,导致错误的await
是在“***”正文中。还是***机构的其他含义?非常感谢!
EDIT 区别于其他建议的(类似)问题here:我的问题不涉及 httpGet,其他一些上下文不同,最重要的是我收到了答案这为我解决了这个问题,与另一个问题的(单独)答案中给出的建议不同。因此,虽然我能够在这里找到解决方案,但我相信保留我的问题对于普通观众来说是有价值的。
var data;
await getData();
document.body.write(data);
async function getData()
const res = await fetch("https://jsonplaceholder.typicode.com/posts",
method: 'GET',
headers:
'Accept': 'application/json, text/plain, */*',
'Content-type': 'application/json'
);
data = await res.json();
【问题讨论】:
of modules — 这可能不是一个模块,而只是全局代码? 它肯定不是栈 sn-p 中的一个模块。 是否需要将 fetch 调用封装在 getData() 方法中? 这能回答你的问题吗? How to resolve the Syntax error : await is only valid in async function? 它没有,因此它是评论而不是我的答案的一部分。 【参考方案1】:***await
表示您正在尝试在async
函数之外使用async/await
语法。解决方法是创建一些功能,例如main
并把代码放进去。
async function main()
var data;
await getData();
document.body.write(data);
main();
有一天*** async/await 将得到支持,并且有一个提案。同时你可以使用这个 babel 插件来使用它 https://babeljs.io/docs/en/babel-plugin-syntax-top-level-await 没有像 main
这样的包装函数。
【讨论】:
谢谢。所以我只需要在它周围放一个包装,仅此而已?从句法/逻辑上讲,重点/区别是什么? 我的意思是,如果我在它周围放置一个包装器,那么我将需要从另一个函数调用它——我不想异步调用它。我希望在执行继续之前完成 fetch 调用并加载所有数据。有什么方法可以实现吗? 好吧,await
只是 Promises 的语法糖。它将等待 promise 解决,然后执行下面的代码,但由于 HTTP 请求是异步的,因此也可能会执行一些其他代码。所以它应该满足你的需要,它会等待getData
执行,然后document.body.write
调用将被执行。
这正是问题所在。如果我不等待,那么“一些其他代码”会在数据下载完成之前执行,这会导致不需要的行为。
您可以在脚本中调用包装器,包装器将包含您必须执行的所有代码,并且因为您输入了await
,代码将在执行其他操作之前等待异步请求。如果您想移除异步行为,可以发出 HTTP 请求 sync
。【参考方案2】:
是的,它是全局代码 - 在我的 script.js 文件中。我想还有什么比这更“***”的呢?
正如评论中指出的,问题不是“***”而是“在模块中”。
只有当type
属性要求这样做时,Web 浏览器才会将脚本作为模块加载:
<script type="module" src="script.js"></script>
这启用了对import
的支持(CORS 允许),使脚本异步加载,并停止***作用域是全局的。
【讨论】:
谢谢!我尝试添加 type="module" 属性,到目前为止它似乎已经奏效了!脚本停止并等待函数调用完成,然后继续进行。所以有一个解决方案!我也很欣赏其他回复,但显然可以做到,不像他们所说的那样。以上是关于全局调用异步函数时出错:“等待仅在异步函数和模块的顶层主体中有效”?的主要内容,如果未能解决你的问题,请参考以下文章
调用异步任务芹菜时引发异常:“NameError:未定义全局名称*”