当前位置: 首页 > news >正文

关于Generator,async 和 await的介绍

在本篇文章中我们主要围绕下面几个问题来介绍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)); // 第一次 yieldlet z = yield (y / 3); // 第二次 yieldreturn (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 10console.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

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

相关文章:

关于Generator,async 和 await的介绍

在本篇文章中我们主要围绕下面几个问题来介绍async 和await &#x1f370;Generator的作用&#xff0c;async 及 await 的特点&#xff0c;它们的优点和缺点分别是什么&#xff1f;await 原理是什么&#xff1f; &#x1f4c5;我的感受是我们先来了解Generator&#xff0c;在去…...

Redis数据库与GO(二):list,set

一、list&#xff08;列表&#xff09; list&#xff08;列表&#xff09;是简单的字符串列表&#xff0c;按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。List本质是个链表&#xff0c; list是一个双向链表&#xff0c;其元素是有序的&#xff0c;元…...

c++知识点总结

1.把字符串a复制到b里面 #include<iostream> #include<string.h> using namespace std; int main() {char a[110],b[110];cin>>a;int n strlen(a);for(int i 0;i<n1;i){b[i] a[i];}cout<<b;return 0; }2.比较两个字符串的大小 如果a大返回1&…...

无IDEA不Java:快速掌握Java集成开发环境

IntelliJ IDEA是一种强大的Java集成开发环境&#xff0c;是Java开发人员的首选工具之一。本文将介绍IDEA的基本使用方法和常用功能&#xff0c;以帮助初学者快速上手。 安装和配置 首先&#xff0c;需要下载并安装IntelliJ IDEA。在安装完成后&#xff0c;需要配置JDK&#xff…...

9.30学习记录(补)

手撕线程池: 1.进程:进程就是运行中的程序 2.线程的最大数量取决于CPU的核数 3.创建线程 thread t1; 在使用多线程时&#xff0c;由于线程是由上至下走的&#xff0c;所以主程序要等待线程全部执行完才能结束否则就会发生报错。通过thread.join()来实现 但是如果在一个比…...

移动应用中提升用户体验的因素

用户体验&#xff08;UX&#xff09;是任何移动应用程序成功的关键因素。随着数以百万计的应用程序争夺注意力&#xff0c;提供无缝、愉快和高效的体验可能是获得忠实用户或在一次互动后失去忠实用户之间的区别。无论是商业应用程序、游戏还是社交平台&#xff0c;增强用户体验…...

VS与VSCode的区别

文章目录 1. 什么是 Visual Studio 和 Visual Studio Code&#xff1f;Visual Studio&#xff08;VS&#xff09;Visual Studio Code&#xff08;VS Code&#xff09; 2. 主要区别详解性能和资源占用功能和复杂性扩展和自定义适用场景价格 3. 详细对比总结4. 如何选择适合自己的…...

用Python和OpenCV实现人脸识别:构建智能识别系统

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 人脸识别技术在现代社会的各个领域得到了广泛应用,从智能手机的面部解锁到公共场所的安全监控,人脸识别已经成为一项日益重要的技术。本教程将指导你使用Python中的OpenCV库来构建一个简单的人脸检测与识别系统…...

微积分-反函数6.5(指数增长和衰减)

在许多自然现象中&#xff0c;数量的增长或衰减与其大小成正比。例如&#xff0c;如果 y f ( t ) y f(t) yf(t) 表示在时间 t t t 时某种动物或细菌种群的个体数量&#xff0c;那么似乎可以合理地假设增长速率 f ’ ( t ) f’(t) f’(t) 与种群 f ( t ) f(t) f(t) 成正比…...

C初阶(十二)do - while循环 --- 致敬革命烈士

大家国庆看阅兵仪式和天安门升旗仪式了吗&#xff1f;岁月安好&#xff0c;只因有人负重前行。 ————山那边是什么 ————是烈士的英魄 ————是他们拼死保卫的新中国 ————河那边是什么 ————是绵延的战火 ————她望着远方泪一滴滴的落 ————和平来了 ——…...

从零开始:SpringBoot实现古典舞在线交流平台

第二章 相关技术介绍 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xf…...

AL生成文章标题指定路径保存:创新工具助力内容创作高效启航

在信息爆炸的时代&#xff0c;一个吸引人的标题是文章成功的第一步。它不仅要准确概括文章内容&#xff0c;还要能激发读者的好奇心&#xff0c;促使他们点击阅读。随着人工智能技术的飞速发展&#xff0c;AL生成文章标题功能正逐渐成为内容创作者的新宠&#xff0c;看看它是如…...

java基础知识汇总

以下内容是学习《java核心技术卷1》的学习笔记 一、一个简单的java应用程序 public class App { public static void main(String[] args) { System.out.println("yuanyexiaolu"); } } 代码解释&#xff1a; 关键字public称为访问修饰符&#xff0c;这些修饰…...

2.点位管理|前后端如何交互——帝可得后台管理系统

目录 前言点位管理菜单模块1.需求说明2.库表设计3.生成基础代码0 .使用若依代码生成器最终目标1.创建点位管理2.添加数据字典3.配置代码生成信息4.下载代码并导入项目 4.优化菜单——点位管理1.优化区域管理2.增加点位数3. 合作商4.区域管理中添加查看详情功能5.合作商添加点位…...

Redis基础二(spring整合redis)

Springboot整合Redis 一、Springboot整合redis ​ redis可以通过使用java代码来实现 第一部分文档中 在终端操作redis的所有命令&#xff0c;Spring已经帮我们封装了所有的操作&#xff0c;所以变得很简单了。 ​ Spring专门提供了一个模块来进行这些操作的封装&#xff0c;这…...

JAVA开源项目 教学资源库系统 计算机毕业设计

本文项目编号 T 067 &#xff0c;文末自助获取源码 \color{red}{T067&#xff0c;文末自助获取源码} T067&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计5.4.1 管…...

二分查找算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 对于二分查找算法不是很了解或者只了解一部分的小伙伴一定要去看下面这篇博客&#xff1a;二分查找算法的介绍与另外一种查找方…...

[Python] 编程入门:理解变量类型

文章目录 [toc] 整数常见操作 浮点数字符串字符串中混用引号问题字符串长度计算字符串拼接 布尔类型动态类型特性类型转换结语 收录专栏&#xff1a;[Python] 在编程中&#xff0c;变量是用于存储数据的容器&#xff0c;而不同的变量类型则用来存储不同种类的数据。Python 与 C…...

C(九)while循环 --- 军训匕首操情景

匕首操&#xff0c;oi~oi~oi~~~~~ 接下来的几篇推文&#xff0c;杰哥记录的是三大循环结构的运行流程及其变式。 本篇的主角是while循环。&#x1f449; 目录&#xff1a; while循环 的组成、运行流程及其变式关键字break 和 continue 在while 循环中的作用while 循环的嵌套题目…...

C#秒如何转为时分秒格式

将秒数转换为分钟和秒数可以通过简单的数学运算来实现。假设你有一个整数表示秒数,可以通过以下方式转换为分钟: 将秒数除以 3600 来获取时钟的整数部分。 将秒数求余 3600的结果除以60 来获取分钟的整数部分。 用秒数求余 60 来获取余下的秒数。 具体实现函数如下: //…...

Awesome-Dify-Workflow:重新定义AI工作流编排的模块化解决方案

Awesome-Dify-Workflow&#xff1a;重新定义AI工作流编排的模块化解决方案 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程&#xff0c;自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/aw/Aweso…...

C语言assert断言:从核心原理到工程实践的全方位指南

1. 项目概述&#xff1a;为什么assert是C程序员的“随身听诊器” 在C语言的世界里摸爬滚打久了&#xff0c;你肯定遇到过这种场景&#xff1a;程序在开发环境里跑得好好的&#xff0c;一到测试环境就莫名其妙崩溃&#xff1b;或者某个函数昨天还能用&#xff0c;今天加了几行代…...

2025_NIPS_Team-PSRO for Learning Approximate TMECor in Large Team Games via Cooperative Reinforce...

文章核心总结与翻译 一、主要内容 本文聚焦双人零和团队博弈(如桥牌、足球),针对现有算法要么仅适用于小型博弈且有博弈论保证,要么能扩展到大型博弈但缺乏理论保证的问题,提出了两种基于策略空间响应预言机(PSRO)的改进算法,旨在高效学习近似团队协调最大最小均衡(…...

Python初学者项目练习28--移除列表中的多个元素

一、练习题目 定义一个函数&#xff0c;该函数用于从第一个列表list1中移除所有存在于第二个列表list2中的元素 二、代码 1.初始版本 代码如下&#xff1a; def remove_number(list1, list2):for i in range(list1):for j in range(list2):if i j:list1.remove(j)return list1…...

四旋翼无人机深度强化学习控制框架与实战优化

1. 四旋翼无人机端到端深度强化学习框架解析四旋翼无人机的自主飞行控制一直是机器人学领域的核心挑战。传统PID控制虽然稳定可靠&#xff0c;但在复杂动态环境中表现受限。深度强化学习&#xff08;DRL&#xff09;通过模拟环境交互实现智能决策&#xff0c;为无人机控制带来了…...

答辩前一天才慌?paperxie 帮我把毕业论文 PPT 的 “地狱副本” 打成了 “新手教程”

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AI PPThttps://www.paperxie.cn/ppt/createhttps://www.paperxie.cn/ppt/create 距离本科毕业论文答辩只剩 3 天&#xff0c;我对着空白的 PPT 页面&#xff0c;第 10 次删掉了刚写好的标题。 导师说我的内…...

DeepSeek MoE训练稳定性突破(动态负载均衡+梯度裁剪双保险):解决专家坍缩的工业级方案

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;DeepSeek MoE架构解析 DeepSeek MoE&#xff08;Mixture of Experts&#xff09;是一种面向大语言模型高效推理与训练的稀疏化架构设计&#xff0c;其核心思想是在保持模型总参数量庞大的前提下&#xff0c;仅…...

RISC-V PMP物理内存保护:硬件级隔离机制与嵌入式系统实战配置

1. 项目概述&#xff1a;为什么我们需要物理内存保护&#xff1f;在嵌入式系统、实时操作系统乃至一些对可靠性要求极高的服务器场景里&#xff0c;系统崩溃往往不是由复杂的逻辑错误直接导致的&#xff0c;而是源于一些看似“低级”的内存访问越界。想象一下&#xff0c;你正在…...

幻兽帕鲁服务器从1.4.1升级到1.5.0踩坑实录:Docker镜像更新、客户端兼容性与回滚指南

幻兽帕鲁服务器1.5.0升级全流程实战&#xff1a;从风险评估到完美回滚 当游戏社区还沉浸在1.4.1版本的稳定体验时&#xff0c;1.5.0版本的更新公告已经在玩家群中激起千层浪。作为服务器管理员&#xff0c;每次版本迭代都像走在钢索上——新特性带来的诱惑与未知风险永远并存。…...

【佛山大学主办,土木与交通学院承办 | 施普林格Springer系列出版 | EI、Scopus检索 | 另期刊论文征稿】第九届结构工程与工业建筑国际学术会议(ICSEIA 2026)

第九届结构工程与工业建筑国际学术会议&#xff08;ICSEIA 2026&#xff09; 2026 9th International Conference on Structural Engineering and Industrial Architecture 2026年7月3-5日 中国佛山 大会官网&#xff1a;www.icseia.com【论文投稿】 截稿时间&#xff1a;…...