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

【高频考点精讲】async/await原理剖析:Generator和Promise的完美结合

async/await原理剖析:Generator和Promise的完美结合

今天咱们聊聊async/await,这玩意儿用起来是真香,但你知道它背后是怎么运作的吗?其实它就是GeneratorPromise的"爱情结晶"。

1. 先搞懂Generator

Generator(生成器)是ES6引入的一个特殊函数,它能在执行过程中暂停和恢复。听起来像不像async/await?没错,async/await的底层就是基于Generator的。

function* myGenerator() {yield '第一步';  // 暂停,返回'第一步'yield '第二步';  // 再次暂停,返回'第二步'return '结束';   // 结束生成器
}const gen = myGenerator();
console.log(gen.next());  // { value: '第一步', done: false }  
console.log(gen.next());  // { value: '第二步', done: false }  
console.log(gen.next());  // { value: '结束', done: true }  

yield就像是一个"暂停按钮",每次调用next(),函数就会执行到下一个yieldreturn

全栈老李小贴士Generator本身并不能自动执行异步操作,它只是提供了一种"暂停-恢复"的机制。

2. Promise:异步操作的基石

Promise大家都熟,它代表一个异步操作的最终状态(成功或失败)。async/awaitawait后面必须跟一个Promise,否则它就没意义了。

function fetchData() {return new Promise((resolve) => {setTimeout(() => resolve('数据来了'), 1000);});
}fetchData().then(data => console.log(data));  // 1秒后输出"数据来了"

3. async/awaitGenerator + Promise的完美结合

async/await本质上是一个语法糖,它让Generator自动执行,并且让yield等待Promise完成。

3.1 async函数返回一个Promise

async function getData() {return "全栈老李的数据";
}getData().then(data => console.log(data));  // 输出"全栈老李的数据"

3.2 await让异步代码看起来像同步

async function fetchUser() {const response = await fetch('https://api.example.com/user');  // 等待Promise完成const data = await response.json();  // 再等待解析JSONconsole.log(data);
}

全栈老李解析await其实就是yield的升级版,它会自动等待Promise完成,然后继续执行后续代码。

4. 手写一个简化版async/await

为了更深入理解,咱们用GeneratorPromise模拟async/await

function runGenerator(generatorFunc) {const gen = generatorFunc();function handleNext(value) {const result = gen.next(value);if (result.done) return Promise.resolve(result.value);return Promise.resolve(result.value).then(handleNext).catch(err => gen.throw(err));  // 错误处理}return handleNext();
}function* mockAsync() {const data1 = yield Promise.resolve('第一步');console.log(data1);  // "第一步"const data2 = yield Promise.resolve('第二步');console.log(data2);  // "第二步"
}runGenerator(mockAsync);

全栈老李解读

  1. runGenerator负责自动执行Generator
  2. 每次yield返回一个PromisehandleNext会等待它完成,再把结果传给下一个next()
  3. 如果Promise被拒绝,会通过gen.throw抛出错误。

5. 使用场景

5.1 多个异步操作依赖执行

async function getUserPosts(userId) {const user = await fetch(`/users/${userId}`);const posts = await fetch(`/users/${userId}/posts`);return { user, posts };
}

5.2 错误处理更直观

async function fetchData() {try {const data = await fetch('/api/data');return data.json();} catch (error) {console.error('全栈老李提醒:请求失败', error);}
}

6. 课后作业(面试题)

题目:下面代码的输出顺序是什么?

async function test() {console.log(1);await Promise.resolve().then(() => console.log(2));console.log(3);
}console.log(4);
test();
console.log(5);

要求

  1. 在评论区写出你的答案和解析。
  2. 我会随机抽几位同学的答案进行点评哦~

全栈老李提示:注意await的微任务机制和事件循环的关系!


好了,今天的内容就到这里,如果你觉得有用,别忘了点赞关注"全栈老李",咱们下期再见! 🚀

http://www.xdnf.cn/news/141265.html

相关文章:

  • RTMP 入门指南
  • Aloudata Agent :基于 NoETL 明细语义层的分析决策智能体
  • Linux阻塞与非阻塞I/O:从原理到实践详解
  • 学硕热度下降,25西电数学与统计学院(考研录取情况)
  • 高频面试题:如何保证数据库和es数据一致性
  • ES历史版本下载
  • 第TR5周:Transformer实战:文本分类
  • 图像识别系统 - Ubuntu部署指南(香橙派开发板测试)-学习记录1
  • MySQL 详解之函数:数据处理与计算的利器
  • HOW - 如何模拟实现 gpt 展示答案的交互效果
  • form表单提交前设置请求头request header及文件下载
  • 线程怎么创建?Java 四种方式一网打尽
  • uniapp 仿企微左边公司切换页
  • FreeRTOS
  • 斗鱼娱乐电玩平台源码搭建实录
  • 短视频矩阵系统可视化剪辑功能开发,支持OEM
  • QT 连接数据库操作(15)
  • Pandas 数据导出:如何将 DataFrame 追加到 Excel 的不同工作表
  • 银发科技:AI健康小屋如何破解老龄化困局
  • MYSQL之数据类型
  • 【MySQL】3分钟解决MySQL深度分页问题
  • git 命令集
  • 【Web应用服务器_Tomcat】一、Tomcat基础与核心功能详解
  • 如何配置Spark
  • Spring-Framework源码环境搭建
  • 7.10 GitHub Sentinel CLI开发实战:Python构建企业级监控工具的5大核心技巧
  • JMeter添加HTTP请求默认值元件的作用详解
  • 百度打响第一枪!通用超级智能体时代,真的来了
  • 常用第三方库:flutter_boost混合开发
  • Android Kotlin 依赖注入全解:Koin appModule 配置与多 ViewModel 数据共享实战指南