Javascript 仅允许在异步函数和模块顶级使用 “await“

news2024/11/23 12:47:57

这个错误的原因,是我们在一个普通函数里调用了async函数,因为async 函数是异步函数,它返回一个 Promis,await必须与async一同出现。所以这里普通函数无法调用它。

async和await只是使函数调用看起来像同步而已,比如下面的示例:

<html>  
    <head>        
        <title>My Website</title>    
        
    </head>    
    <body>        
        <script type="text/javascript">
            // 定义一个返回 Promise 的异步函数
            function fetchData() {
                return new Promise((resolve) => {
                    setTimeout(() => {
                        resolve("数据获取成功!");
                    }, 5000);
                });
            }

            // 使用 async 和 await
            async function AsyncFetchData() {
                console.log("开始获取数据...");
                
                try {
                    // 等待 fetchData 函数返回的 Promise
                    const result = await fetchData();
                    // 输出fetchData 函数的PromiseResult
                    console.log("fetchData()的结果--->"); 
                    console.log(result); 
                } catch (error) {
                    console.error("获取数据失败:", error);
                }
            }

            // 程序调用async函数
            function main() {
                console.log("程序开始执行");
                AsyncFetchData();
                console.log("程序执行完毕");
            }

            main();

        </script>
    </body>    
</html>

执行结果:

等待几秒钟后:

我们把AsyncFetchData()方法的代码拷贝进main(),从执行结果,我们可以看出其执行顺序是将AsyncFetchData()方法分隔成了两部分运行 (以await那一行代码为分割线),

function main() {
    console.log("程序开始执行"); // main()

    //AsyncFetchData()上半部分 begin
    {async function AsyncFetchData() {
                console.log("开始获取数据...");
                
                try {
                    // 等待 fetchData 函数返回的 Promise
                    const result = await fetchData();} 
    //AsyncFetchData()上半部分 end

    console.log("程序执行完毕");  // main()

    //AsyncFetchData() 下半部分 begin
    {
            // 输出fetchData 函数的PromiseResult
            console.log("fetchData()的结果--->"); 
            console.log(result); 
         } catch (error) {
            console.error("获取数据失败:", error);
        }
    } 
    //AsyncFetchData() 下半部分 end
}

main()执行到AsyncFetchData()方法的await时,就会直接进行main()的其他代码,直到Promise返回结果后才会执行AsyncFetchData()方法的await后的代码。

如果我们非要main()内部是同步运行,我们使用await 调用AsyncFetchData()方法来等待其执行完毕,会遇到 仅允许在异步函数和模块顶级使用 "await" 错误,因为main是普通函数

必须把main()也定义为异步函数:

// 程序调用async函数
async function main() {
     console.log("程序开始执行");
     await AsyncFetchData();
     console.log("程序执行完毕");
}

main();

结果显示,是同步运行:

但是因为main()也是异步函数,如果它被其他普通函数调用,main()函数也会被从await分成两部分运行。

所以async和await只是使函数调用看起来像同步而已

另外,假如异步函数有返回值的话,返回的仍然是Promise对象,可以使用.then()做回调:

        async function AsyncFetchData() {
                console.log("开始获取数据...");
                
                try {
                    // 等待 fetchData 函数返回的 Promise
                    const result = await fetchData();
                    // 输出fetchData 函数的PromiseResult
                    console.log("fetchData()的结果--->"); 
                    console.log(result); 
                    return result;//返回Promise
                } catch (error) {
                    console.error("获取数据失败:", error);
                }
            }

            // 程序调用async函数
            function main() {
                console.log("程序开始执行");
                AsyncFetchData().then((re)=>{
                    console.log("AsyncFetchData的返回--->");
                    console.log(re);
                });
                console.log("程序执行完毕");
            }

            main();

结果如下,注意仍然是异步执行。

延申:

如果有多个异步函数,它们的执行时间不一样,我们如何保证能按照顺序获得结果而不乱套呢。答案是使用Promise.all():

            const promise1 = new Promise((resolve) => {
                setTimeout(() => resolve("结果1"), 3000); // 3秒后 resolved
            });

            const promise2 = new Promise((resolve, reject) => {
                setTimeout(() => resolve("结果2"), 5000); // 5秒后 resolved
            });

            const promise3 = new Promise((resolve, reject) => {
                setTimeout(() => resolve("结果3"), 2000); // 2秒后 resolved
            });

            // 使用 Promise.all
            Promise.all([promise1, promise2, promise3])
                .then((results) => {
                    console.log(results); 
                })
                .catch((error) => {
                    console.error("捕获到错误:", error); 
                });

三个异步函数的执行时间是混乱的,我们使用Promise.all()可以按照顺序得到结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2209461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MMMLP】核心方法解读

此方法用于顺序推荐&#xff0c;和我的研究方向不一样&#xff0c;所以这里只探讨值得借鉴的部分 abstract&#xff1a; 现有的顺序推荐方法要么不能直接处理多模态&#xff0c;要么计算量大。为了解决这个问题&#xff0c;我们提出了一种新的多模态多层感知器&#xff08;MM…

MYSQL-windows安装配置两个或多个版本MYSQL

安装第一个mysql很简单&#xff0c;这里不再赘述。主要说说第二个怎么安装&#xff0c;服务怎么配置。 1. 从官网下载第二个MySQL并安装 一般都是免安装版了&#xff0c;下载解压到某个文件目录下(路径中尽量不要带空格或中文)&#xff0c;再新建一个my.ini文件&#xff08;或…

QGroundControl最新版本MacOS平台编译(使用CMakeLists.txt)

1.下载源码: git clone https://github.com/mavlink/qgroundcontrol.git --recursive 2.安装依赖: brew install GStreamer 设置环境变量:GST_PLUGIN_PATH 安装SDL2: brew install SDL2

C#自定义特性

特性的用处 一般用来影响某一个类的个别字段或者方法 定义特性 需要将类继承Attribute 可以通过构造函数的方式影响使用特性的方法 可以通过给自定义的特性通过加AttributeUsage特性的方法进行进一步管理 AttributeUsage特性默认传三个参数 第一个参数一般用来约束此自定义…

怎么把m4a转换成mp3?8种关于m4a转成MP3格式的转换方法

怎么把m4a转换成mp3&#xff1f;尽管m4a格式在音质上表现突出&#xff0c;但并不是所有设备和软件都能支持&#xff0c;给一些用户带来了不便。为了保证音乐文件能够在更多设备和平台上播放&#xff0c;许多人选择将m4a转换为MP3格式。MP3几乎可以在所有播放器和设备上使用&…

LeetCode讲解篇之2320. 统计放置房子的方式数

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们首先发现一个规律街道两侧是否放置房子是独立的&#xff0c;即放置房子的方式数 一侧放置房子的方式数 * 另一侧放置房子的方案数 一侧放置房子的方式数的二次方 对于一侧[0, i]范围内地块放置房子的方式…

starrocks-删除表字段

1、背景 之前做了个大宽表&#xff0c;将近100个字段&#xff0c;但是后来发现很多字段在实际生产上都没有用到&#xff0c;并且随着数据量的增加&#xff0c;给集群的存储以及消费任务的解析带来了比较大的压力。所以决定对字段做删除处理。 当前的表是使用routine load任务从…

渗透测试 之 AD域渗透 【AS-REP Roasting】 攻击技术详解

说明: AS-REP Roasting是一种对用户账户进行离线爆破的攻击方式。但是该攻击方式使用比较受限&#xff0c;因为其需要用户账户设置“不要求Kerberos预身份验证”选项&#xff0c;而该选项默是没有勾选的。Kerberos 预身份验证发生在Kerberos身份验证的第一阶段&#xff08;AS_…

14. 最长公共前缀【字符串】

文章目录 14. 最长公共前缀解题思路Go代码 14. 最长公共前缀 14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow&…

STM32 QSPI接口驱动GD/W25Qxx配置简要

STM32 QSPI接口GD/W25Qxx配置简要 &#x1f4dd;本篇会具体涉及介绍Winbond&#xff08;华邦&#xff09;和GD(兆易创新) NOR flash相关型号指令差异。由于网络上可以搜索到很多相关QSPI相关知识内容&#xff0c;不对QSPI通讯协议做深度解析。 &#x1f516;首先确保所使用的ST…

2022年10月自考《数据库系统原理》04735试题

目录 一.单选题 二.填空题 三.设计题 四.简答题 五.综合题 一.单选题 1.数据库系统管理员的英文缩写是 (书中)P29页 A.Data B.DB C.DBA D.DBS 2.客户/服务器模式中&#xff0c;客户端和服务器可以同时工作在同一台计算机上&#xff0c;该方式称为 (书中)P37页 A.单机方…

使用Copilot自动在Rstudio中写代码,提高效率!

原文链接&#xff1a;使用Copilot自动在Rstudio中写代码&#xff0c;提高效率&#xff01; 2022年教程总汇 2023年教程总汇 引言 今天我们分享&#xff0c;在Rstuido中使用copilot自动写代码&#xff0c;提高你的分析和绘图效率。 copilot是2024年9月后引入到Rstuido中&…

如何在 IDEA 中导入 Java 项目的 Git 仓库并启动

目录 前言1. 从 Git 仓库导入 Java 项目2. 配置 Maven2.1 配置 Maven 仓库和设置文件2.2 加载依赖 3. 配置 Tomcat 并运行项目3.1 配置 Tomcat3.2 配置 Server URL3.3 启动项目 4. 常见问题与解决方法4.1 Maven 依赖无法下载4.2 Tomcat 部署失败4.3 项目启动后无法访问 结语 前…

从RNN讲起——序列数据处理网络

文章目录 RNN&#xff08;Recurrent Neural Network&#xff0c;循环神经网络&#xff09;1. 什么是RNN&#xff1f;2. 经典RNN的结构3. RNN的主要特点4. RNN存在问题——长期依赖&#xff08;Long-TermDependencies&#xff09;问题 LSTM&#xff08;Long Short-Term Memory&a…

使用libssh2实现多线程模式的文件上传与下载

使用libssh2实现多线程模式的文件上传与下载 一、准备工作二、初始化SSH连接三、文件上传与下载四、多线程处理五、总结libssh2 是一个开源的SSH库,用于在C/C++程序中实现SSH2协议的功能。通过libssh2,我们可以方便地进行远程登录、执行命令、上传和下载文件等操作。在多线程…

一区大黄蜂!人工蜂群算法优化!ABC-CNN-LSTM-MATT多特征分类预测

一区大黄蜂&#xff01;人工蜂群算法优化&#xff01;ABC-CNN-LSTM-MATT多特征分类预测 目录 一区大黄蜂&#xff01;人工蜂群算法优化&#xff01;ABC-CNN-LSTM-MATT多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现ABC-CNN-LSTM-MATT人工蜂群…

c++关于内存的知识点上速成

温馨提示&#xff1a;本篇文章的内容涉及的是c内存的管理方式 c内存管理的方式 new的使用方式 类型 对象名 new 类型 注意&#xff1a;如果对象名前面的类型有星号&#xff0c;后面的类型&#xff08;new后面的&#xff09;不需要星号 样例&#xff1a; delete的使用方…

VMDK 0X80BB0005 VirtualBOX虚拟机错误处理-数据恢复——未来之窗数据恢复

打开虚拟盘文件in7.vmdk 失败. Could not get the storage format of the medium 7\win7.vmdk (VERR_NOT_SUPPORTED). 返回 代码:VBOX_E_IPRT_ERROR (0X80BB0005) 组件:MediumWrap 界面:IMedium {a a3f2dfb1} 被召者:IVirtualBox {768 cd607} 被召者 RC:VBOX_E_OBJECT_NOT_F…

生成式专题的第四节课--CycleGAN

CycleGAN&#xff08;Cycle-Consistent Generative Adversarial Network&#xff0c;循环生成对抗网络&#xff09;是一种用于无监督图像转换的深度学习模型&#xff0c;即一种用于图像到图像转换任务的生成对抗网络&#xff08;GAN&#xff09;的变体&#xff0c;它可以在没有…

团标大数据(2024年09月)

一、总体数据 截至2024年09月30日&#xff0c;共有8240家社会团体在全国团体标准信息平台注册&#xff0c;其中民政部登记注册的有973家&#xff0c;地方民政部门登记注册的有7267家。社会团体在平台共计公布89857项团体标准&#xff0c;其中民政部登记注册的社会团体公布3603…