Async/Await

news/2024/10/30 23:22:52/

参考链接:

async、await 实现原理

async 和 await

1.异步编程回顾

由于 JavaScript 是单线程执行模型,因此必须支持异步编程才能提高运行效率。异步编程的语法目标是让异步过程写起来像同步过程。

异步编程的发展经历了:  回调函数PromiseES7中的async/await

Promise函数在这里不赘述,会另外写一篇Promise的总结,所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

2.async/await

实际上,async/await就是Generator + Promise的语法糖,await必须在async内使用,并装饰一个Promise对象,async返回的也是一个Promise对象。

async 是异步的意思,await 则可以理解为等待。放到一起可以理解async就是用来声明一个异步方法,而 await 是用来等待异步方法执行。

async

async 声明的函数返回一个 Promise 对象,它可以包含多个 await 表达式,这些表达式后面通常跟随着 Promise 对象。当遇到 await 表达式时,async 函数会暂停执行,等待 Promise 对象的状态改变(即 resolvereject,然后恢复执行,并将 resolve 的结果作为 await 表达式的值返回。

所以,对于async关键字,以下两种方法是等效的:

await

而对于await函数,正常情况下,await命令后面是一个Promise对象,返回该对象的结果。如果不是Promise对象,就直接返回对应的值。

在这段代码中,先定义了一个异步函数f,它会返回一个立即resolved的Promise对象,其resolved值为123。然后,通过调用f函数,并使用then方法注册回调函数的方式来获取函数返回的Promise对象。

在异步函数f中:

  • async function 关键字声明了这是一个异步函数,它会返回 Promise 对象,而且在函数中可以使用 await 表达式。
  • return await 123 表示等待 Promise 对象 123 的状态改变(即立即被 resolve),然后将其 resolve 的结果作为函数返回值返回。由于 123 不是一个 Promise 对象,会自动被包装成一个 resolved 状态的 Promise 对象返回,因此其实等价于直接返回 123

因此,这个异步函数 fn1 的返回值实际上就是 Promise.resolve(123),也就是一个立即 resolve 的 Promise 对象,其 resolved 的值为 123

然后这句代码:

f().then(v => console.log(v))
  1. 调用 fn1() 函数,返回一个 Promise 对象。
  2. 使用 then 方法在该对象上注册回调函数,该回调函数的参数 v 就是 Promise 对象 resolve 的值。
  3. 在回调函数中,调用 console.log(v) 打印该值。

示例分析

例1

 

async/await函数的执行顺序:

遇到await时,执行await后面的内容,但是会阻塞下面的代码(即加入微任务队列),先执行 async 外面的同步任务,同步代码执行完,再回到 async 函数中,再执行之前阻塞的代码。

 

例2:使用 async/await 结合 setTimeout 实现每隔1s 打印一个等于号的功能

async function printEqual() {while(true) {await new Promise((resolve) => setTimeout(resolve, 1000)) // 等待 1sconsole.log('=')}
}printEqual()

当我们使用 await 关键字等待一个异步函数时,该异步函数必须返回一个 Promise 对象。在这种情况下,await 表达式会暂停当前函数的执行,等待 Promise 对象状态变为 resolved 后恢复执行。同时,由于异步函数本身是不会被阻塞的,因此可以避免阻塞主线程。

在本例中,使用 await 等待了一个 Promise 对象,该 Promise 对象使用 setTimeout 方法创建,实现了一定时间后返回一个 resolved 状态的 Promise,然后通过调用 resolve 函数来设置 Promise 的状态并返回结果。因为 setTimeout 会在一定时间后触发传入的回调函数,所以使用 setTimeout(resolve, 1000) 意味着将在 1 秒后出发 resolve 函数,从而返回一个 resolved 的 Promise 对象。在使用 await 后,程序将会等待 1 秒的时间,然后继续执行 await 之后的代码。

综上所述,await new Promise((resolve) => setTimeout(resolve, 1000)) 表示等待 1 秒钟之后再执行下一步操作,由于是异步的,因此不会阻塞主线程。

 


http://www.ppmy.cn/news/83090.html

相关文章

复杂软件版本如何使用git工具进行管理

1.需求说明 一个项目,如果长期开发下去,我们会碰到各种各样的客户,然后就会有各种各样的需求。这时候就会出现一个问题:如果我们的代码都是一个项目,客户的主体流程都是一样,但部分客户又有一些特别的定制…

数字人的新革命,BAT的“冲高”战场

配图来自Canva可画 ChatGPT横空出世,让人们看到了数字人的另一种可能,将ChatGPT与虚拟数字人融合,研发出更加智能化、拟人化的虚拟数字人成为数字人厂商的新命题、新方向。 2月份,岭南股份、风语筑、开普云等10多家公司&#xf…

java多线程同步技术基础

说明 当程序中出现多个进程对同一资源进行操作时,因为对数据的操作非常密集,可能会对资源过度操作,这时就需要用到线程的同步技术。 以一个抢红包程序为例,红包数量为3个,开启5个线程来模拟抢红包行为,红…

Python实现ACO蚁群优化算法优化卷积神经网络回归模型(CNN回归算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蚁群优化算法(Ant Colony Optimization, ACO)是一种源于大自然生物世界的新的仿生进化算法&#xff0c…

深入学习MYSQL-使用触发器

触发器 每个表最多支持6个触发器,(insert,update,delete)之前和之后。 删除触发器 drop trigger trigger_name;insert 触发器  在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入…

API测试| 了解API接口测试| API接口测试指南

什么是API? API是一个缩写,它代表了一个 pplication P AGC软件覆盖整个房间。API是用于构建软件应用程序的一组例程,协议和工具。API指定一个软件程序应如何与其他软件程序进行交互。 例行程序:执行特定任务的程序。例程也称为过…

搭建监控日志系统

在微服务或者集群架构中,一次请求的调用会跨多个服务(web,mysql,feign等)、多个模块(用户模块,商品模块等)、多个容器(用户模块可能有多个实例),这…

Unity之OpenXR+XR Interaction Toolkit 安装和配置

前言 XR Interaction Toolkit 是Unity基于OpenXR标准,发布的一套XR工具,目的是方便我们快速接入XR相关的SDK,并且做到兼容不同VR设备的目的,目前流行的VR设备如Oculus,Metal,HTC Vive,Pico等统统都支持。 所以我们今天的目的就是把XR Interaction Toolkit从导入到配置,…