关于Generator,async 和 await的介绍

news2024/11/29 10:39:01

在本篇文章中我们主要围绕下面几个问题来介绍async 和await

🍰Generator的作用,async 及 await 的特点,它们的优点和缺点分别是什么?await 原理是什么?

📅我的感受是我们先来了解Generator,在去思考async 及 await 的问题这样更有利一点

Generator

🎆Generator是一种特殊的函数,它可以暂停和恢复其执行。也就是说该函数可以“中断”并在稍后恢复其执行状态,而不是从头开始执行。这使得生成器非常适用于处理大型数据流或异步操作,因为它可以有效地管理内存和资源。
文字太过于难理解,直接上实例:
使用Generator的时候我们需要可以通过 yieldnext() 的使用来达到效果。

function *foo(x) {
let y = 2 * (yield (x + 1))
let z = yield (y / 3)
return (x + y + z)
}
let it = foo(5)
console.log(it.next()) // => {value: 6, done: false}
console.log(it.next(12)) // => {value: 8, done: false}
console.log(it.next(13)) // => {value: 42, done: true}

🚀yield 和 **next()**的介绍:

🔰yield 关键字用于生成值并挂起生成器的执行。
🔰 next() 方法用于从生成器获取下一个值。每次调用 next()
时,生成器会从上次暂停的地方继续执行,直到遇到下一个 yield 或者执行结束。
认识了这两个知识点后我们在来读懂上面这段代码吧,
分析:

function *foo(x) {
  let y = 2 * (yield (x + 1)); // 第一次 yield
  let z = yield (y / 3); // 第二次 yield
  return (x + y + z); // 返回最终结果
}

1️⃣第一次 yield

🔰 (x + 1) 计算出 x 加上 1 的值。
🔰 yield (x + 1) 暂停函数执行,并返回 x + 1 的值作为 yield 的值。

接收值
当 next() 方法被调用时,传递给 next() 方法的值会被赋给 yield 表达式的值。这里 y 的计算依赖于 yield (x + 1) 接收到的值。

2️⃣第二次 yield:

🔰 y / 3 计算出 y 除以 3 的值。
🔰 yield (y / 3) 再次暂停函数执行,并返回 y / 3 的值作为 yield 的值。

再次接收值:
当 next() 方法再次被调用时,传递给 next() 方法的值会被赋给 z。

返回值:
最终返回 x + y + z 的计算结果。

调用生成器函数

let it = foo(5);

初始化生成器 it,传入参数 5。
执行 next() 方法
1️⃣第一次 next()

console.log(it.next()); // => {value: 6, done: false}

🔰 it.next() 调用生成器的 next() 方法。
🔰由于没有传递任何值到 yield 表达式,默认情况下 yield 接收到的值是 undefined
🔰 x + 1 的值为 5 + 1 = 6。
🔰 yield 返回 {value: 6, done: false},表示生成器还没有完成执行。
2️⃣ 第二次 next()

console.log(it.next(12)); // => {value: 8, done: false}

🔰 it.next(12) 调用 next() 并传递值 12。
🔰12 被赋值给 yield 表达式的值,因此 y 的计算为 2 * 12 = 24
🔰y / 3 的值为 24 / 3 = 8
🔰 yield 返回 {value: 8, done: false},表示生成器还没有完成执行。
3️⃣ 第三次 next()

console.log(it.next(13)); // => {value: 42, done: true}

🔰 it.next(13) 调用 next() 并传递值 13。
🔰 13 被赋值给 z。
🔰 计算 x + y + z 的值为 5 + 24 + 13 = 42。
🔰 yield 返回 {value: 42, done: true},表示生成器已经完成执行。

上面就是关于Generator的基本使用以及执行过程。

🚤 async 及 await

🚎asyncawait 是 JavaScript 中用于处理异步操作的关键字,它们使得异步代码看起来更像同步代码,提高了可读性和可维护性。

async 函数

🌌async 关键字用于声明一个函数为异步函数。这样的函数会返回一个 Promise 对象。即使函数体内部没有任何异步操作,async 函数也会返回一个解析为 undefinedPromise

await 表达式

🌌await 关键字只能出现在 async 函数内部,用于等待一个 Promise 对象的结果。当 await 前面的表达式返回一个 Promise 时,await 会阻塞 async 函数的执行,直到 Promise 解析或拒绝。如果 await 前面的表达式返回的是非 Promise 对象,则会立即返回该值。

特点

🔰简化异步编程:使异步代码更加接近同步代码的风格。
🔰自动管理 Promise:async 函数总是返回一个 Promise。
🔰 错误处理:利用 try…catch 处理异步操作中的错误。
🔰非阻塞性:在等待异步操作期间,JavaScript 运行环境可以执行其他任务。
🔰链式调用:支持多个异步操作之间的顺序执行。
🔰返回值和错误处理:明确地处理异步函数的返回值和可能的错误。

原理

🔮一个函数如果加上 async ,那么该函数就会返回一个 Promise

async function test() {
	return "3"
}
	console.log(test()) // -> Promise {<resolved>: "3"}

🔮async 就是将函数返回值使用 Promise.resolve() 包裹了下,和 then 中处理返回值一样,并且 await 只能配套 async 使用

async function demo1() {
	let a = await sleep()
}

🔮asyncawait 相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码,并且能够为我们解决回调地狱问题。

async function demo() {
	// 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式
	// 如果有依赖性的话,其实就是解决回调地狱的例子了
	await fetch(url)
	await fetch(url1)
	await fetch(url2)
}
let a = 0
let b = async () => {
	a = a + await 10
	console.log('2', a) // ——> '2' 10
}
b()
a++
console.log('1', a) // ——> '1' 1

解析上面的代码:

🔰函数 b 先执行,在执行到 await 10 之前变量 a的值还是 0,因为 await 的内部实现了Generator函数,Generator 因为会限制函数执行,所以会保留堆栈内的东西,所以 a = 0 就被保存了下来;
🔰 因为 await 是异步操作,后来的表达式不返回 Promise 的话,就会包装成Promise.reslove(返回值),然后会去执行函数外的同步代码。
🔰同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10。

上述解释中提到了 await 内部实现了 Generator ,其实 await 就是 generator 加上 Promise 的语法糖,且内部实现了自动执行 Generator

今天的分享就到这里啦,感谢大家的阅览,小江会一直与大家一起努力,文章中如有不足之处,你的支持是我前进的最大动力,请多多指教,感谢支持,持续更新中 ……

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

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

相关文章

将视频改成代码滚动

本文章就来讲讲如何将视频转换成代码滚动&#xff0c;也就是这种模式&#xff1a; 本文章就来详细的教大家如何制作达到这种效果吧&#xff01; &#xff08;注&#xff1a;我记得一些python库也可以轻松达到这些效果&#xff0c;但我一时半伙想不起来了&#xff0c;所以这里用…

idea插件开发的第六天-开发一个笔记插件

介绍 Demo说明 本文基于maven项目开发,idea版本为2022.3以上,jdk为1.8本文在JTools插件之上进行开发本插件目标是做一款笔记插件,用于开发者在开发过程中随时记录信息仓库地址: jtools-notes JTools插件说明 Tools插件是一个Idea插件,此插件提供统一Spi规范,极大的降低了id…

手写mybatis之Mapper XML的解析和注册使用

前言 你是怎么面对功能迭代的&#xff1f; 很多程序员在刚开始做编程或者新加入一家公司时&#xff0c;都没有多少机会可以做一个新项目&#xff0c;大部分时候都是在老项目上不断的迭代更新。在这个过程你可能要学习N个前人留下的各式各样的风格迥异的代码片段&#xff0c;在这…

【杂谈一之概率论】CDF、PDF、PMF和PPF概念解释与分析

一、概念解释 1、CDF&#xff1a;累积分布函数&#xff08;cumulative distribution function&#xff09;&#xff0c;又叫做分布函数&#xff0c;是概率密度函数的积分&#xff0c;能完整描述一个实随机变量X的概率分布 2、PDF&#xff1a;连续型概率密度函数&#xff08;p…

平面电磁波的电场能量磁场能量密度相等,能量密度的体积分等于能量,注意电场能量公式也没有复数形式(和坡印廷类似)

1、电场能量密度和磁场能量密度相等(实数场算的) 下面是电场能量密度和磁场能量密度的公式&#xff0c;注意这可不是坡印廷定理。且电场能量密度没有复数表达式&#xff0c;即不是把E和D换成复数形式就行的。注意&#xff0c;一个矢量可以转化为复数形式&#xff0c;两个矢量做…

数据挖掘-padans初步使用

目录标题 Jupyter Notebook安装启动 Pandas快速入门查看数据验证数据建立索引数据选取⚠️注意&#xff1a;排序分组聚合数据转换增加列绘图line 或 **&#xff08;默认&#xff09;&#xff1a;绘制折线图。bar&#xff1a;绘制条形图。barh&#xff1a;绘制水平条形图。hist&…

Discord:报错:A fatal Javascript error occured(解决办法)

按 Windows 键 R 并输入 %appdata% 选择 discord 文件夹并将其删除。 再次按 Windows 键 R 并输入 %LocalAppData% 选择 discord 文件夹并再次将其删除。 附加&#xff1a; 如果还不行&#xff0c;就通过官网下载吧&#xff0c;这个问题通过epic下载可能会有

图文深入理解Oracle DB企业级集中管理神器-GC的安装和部署

值此国庆佳节&#xff0c;深宅家中&#xff0c;闲来无事&#xff0c;就多写几篇博文。今天继续宅继续写。 本文承接上篇&#xff0c;介绍GC的安装和部署。咱们不急&#xff0c;慢慢来&#xff0c;饭要一口一口地吃才能吃得踏实自然。 限于篇幅&#xff0c;本节将重点介绍关键步…

【ubuntu】apt是什么

目录 1.apt简介 2.常用apt指令 2.1安装 2.2更新列表 2.3更新已经安装的软件包 2.4搜索软件包 2.5显示软件包信息 2.6移除软件包 2.7清理无用的安装包 2.8清理无用的依赖项 3.apt和apt-get 3.1区别 3.2 总结 1.apt简介 apt的全称是advanced package …

JAVA的三大特性-封装、继承、多态

Java作为一种面向对象的编程语言&#xff0c;其核心特性包括封装、继承和多态。这三大特性是Java语言的基石&#xff0c;它们相互关联&#xff0c;共同构成了Java强大的面向对象能力。 封装&#xff08;Encapsulation&#xff09; 封装是面向对象编程的一个重要概念&#xff0c…

Pytorch最最适合研究生的入门教程,Q3 开始训练

文章目录 Pytorch最最适合研究生的入门教程Q3 开始训练3.1 训练的见解3.2 Pytorch基本训练框架work Pytorch最最适合研究生的入门教程 Q3 开始训练 3.1 训练的见解 如何理解深度学习能够完成任务&#xff1f; 考虑如下回归问题 由函数 y f ( x ) yf(x) yf(x)采样得到的100个…

现在的新电脑在任务管理器里又多了个NPU?它是啥?

前言 今年中旬各家品牌的新笔记本感觉上都是很不错&#xff0c;搞得小白自己心痒痒&#xff0c;突然间想要真的买一台Windows笔记本来耍耍了。 但今天这个文章并不是什么商品宣传啥的&#xff0c;而是小白稍微尝试了一下新笔记本之后的一些发现。 在今年的新笔记本上都多了一…

【GESP】C++一级练习BCQM3025,输入-计算-输出-6

题型与BCQM3024一样&#xff0c;计算逻辑上稍微复杂了一点点&#xff0c;代码逻辑没变&#xff0c;仍属于小学3&#xff0c;4年级的题目水平。 题解详见&#xff1a;https://www.coderli.com/gesp-1-bcqm3025/ https://www.coderli.com/gesp-1-bcqm3025/https://www.coderli.c…

数据提取之JSON与JsonPATH

第一章 json 一、json简介 json简单说就是javascript中的对象和数组&#xff0c;所以这两种结构就是对象和数组两种结构&#xff0c;通过这两种结构可以表示各种复杂的结构 > 1. 对象&#xff1a;对象在js中表示为{ }括起来的内容&#xff0c;数据结构为 { key&#xff1…

最新版本SkyWalking【10.1.0】部署

这里写目录标题 前言前置条件启动Skywalking下载解压启动说明 集成Skywalking Agent下载Agent在IDEA中添加agent启动应用并访问SpringBoot接口 说明 前言 基于当前最新版10.1.0搭建skywalking 前置条件 装有JDK11版本的环境了解SpringBoot相关知识 启动Skywalking 下载 地…

浑元换算策略和武德换算策略-《分析模式》漫谈36

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的第3章有这么一句&#xff1a; A conversion, however deterministic, does not follow that faithfully. 2004&#xff08;机械工业出版社&#xff09;中译本…

HTB:Explosion[WriteUP]

目录 连接至HTB服务器并启动靶机 1.What does the 3-letter acronym RDP stand for? 2.What is a 3-letter acronym that refers to interaction with the host through a command line interface? 3.What about graphical user interface interactions? 4.What is the…

【MySQL 08】复合查询

目录 1.准备工作 2.多表查询 笛卡尔积 多表查询案例 3. 自连接 4.子查询 1.单行子查询 2.多行子查询 3.多列子查询 4.在from子句中使用子查询 5.合并查询 1.union 2.union all 1.准备工作 如下三个表&#xff0c;将作为示例&#xff0c;理解复合查询 EMP员工表…

深入探究:在双链表的前面进行插入操作的顺序

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd;惟有主动付出&#xff0c;才有丰富的果…

一次解决Go编译问题的经过

用Go语言编写了一个小的项目&#xff0c;项目开发环境是在本地的Windows环境中&#xff0c;一切单元测试和集成测试通过后&#xff0c;计划将项目部署到VPS服务器上自动运行&#xff0c;但在服务器上执行go run运行时&#xff0c;程序没有任何响应和回显&#xff0c;甚至main函…