【问题标题】: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();
}

【问题讨论】:

标签: javascript async-await es6-promise fetch-api


【解决方案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" 属性,到目前为止它似乎已经奏效了!脚本停止并等待函数调用完成,然后继续进行。所以有一个解决方案!我也很欣赏其他回复,但显然可以做到,不像他们所说的那样。
猜你喜欢
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
相关资源
最近更新 更多