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

Node.js 中 async await 与 Generator 函数实现异步的区别对比

Node.js 中 async await 与 Generator 函数实现异步的区别对比

Node.js 从 7.6 版本(2017 年)开始原生支持 async/await,相比 Generator 函数需要配合 co 库使用,async/await 将代码行数减少约 40% 且无需外部执行器。

原因分析

Generator 函数是 ES6 引入的新特性,通过 function* 关键字定义,返回一个迭代器对象,必须手动调用.next() 方法逐步执行。例如:

function* fetchData() {const response = yield fetch('https://api.example.com/data');const data = yield response.json();console.log(data);
}
const iterator = fetchData();
const fetchPromise = iterator.next().value;
fetchPromise.then(response => {iterator.next(response);
});

而 async/await 是 ES2017 标准引入的特性,本质是 Generator 函数的语法糖。async 函数自带执行器,调用方式与普通函数相同,返回值为 Promise 对象。根据 2024 年 6 月 6 日发布的技术分析,async/await 相比 Generator 有四点改进:内置执行器、更好的语义(async 和 await 比*和 yield 更清晰)、更广的适用性(await 后可跟 Promise 或原始类型值)、返回值是 Promise 而非 Iterator。

解决方案

方案一:使用 Generator + co 库(2017 年前主流方案)

在 Node 7.6 之前,需使用 co 库自动执行 Generator 函数。根据 2018 年 3 月 7 日的实战代码:

import co from 'co'
class Preload {*autoExeImageStream() {for(let i = 0; i < this.imgs.length; i++) {if(this.ignore.indexOf(i) == -1) {yield this.loadOneSetImages(this.imgs[i])}}}init() {if(this.auto) {co(this.autoExeImageStream()).then((data) => {console.log('资源加载完毕~')})}}
}

co 库约定 yield 命令后面只能是 Thunk 函数或 Promise 对象,这是 2017 年 Node 7.6 支持 async/await 前的主流方案。

方案二:使用 async/await(2017 年后推荐方案)

Node 7.6 版本(2017 年)原生支持 async/await 后,代码更简洁:

async function asyncFunction() {const result = await Promise.resolve(42);console.log(result);
}
asyncFunction();

根据 2025 年 2 月 17 日的资料,async 函数始终返回 Promise,await 用于等待 Promise 的解决。错误处理使用 try-catch:

async function e() {throw new Error('has Error');
}
e().then(success => console.log('成功', success)).catch(error => console.log('失败', error));

方案三:混合使用场景

根据 2024 年 11 月 1 日的说明,高版本 Node 中可以在顶层使用 await,但 async/await 只能用于函数内部。对于需要暂停和恢复执行的场景,Generator 仍有用武之地,例如实现可中断的异步任务。

注意事项

1. 执行器依赖问题:Generator 函数必须依靠执行器(如 co 库),而 async 函数自带执行器。根据 2026 年 1 月 10 日的资料,可以认为 async 函数 == co + generator 函数。

2. 返回值类型差异:Generator 函数返回 Iterator 对象,需要通过.next() 获取值;async 函数返回 Promise 对象,可直接使用.then() 方法。2024 年 6 月 6 日的测试显示,async 函数接收到返回的值,发现不是异常或 reject,则判定成功,可以 return 各种数据类型的值(false、NaN、undefined 等)。

3. await 后表达式限制:co 模块约定 yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面可以是 Promise 或原始类型的值(Number、string、boolean,但这时等同于同步操作)。

4. 错误处理差异:async 函数内部抛出异常会使 Promise 状态为 reject,进入 catch 分支。根据 2022 年 10 月 20 日的说明,若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。

5. Node 版本兼容性:Node 7.6(2017 年)是首个支持 async/await 的版本,低于此版本需使用 Babel 转译或 Generator+co 方案。

参考来源

来源:AI 考拉技术分享会 - Node.js 异步编程(2026 年 1 月 10 日)

来源:知识库技术文档 - async/await 与 Generator 函数对比(2025 年 2 月 17 日)

来源:CSDN 博客 - Js 的 Promise、Generator,Async/await 区别(2022 年 11 月 28 日)

来源:阿里云开发者社区 - async 和 await(2022 年 10 月 20 日)

原文链接:https://www.zjcp.cc/ask/9683.html

http://www.jsqmd.com/news/754944/

相关文章:

  • Java集成OpenAI API:kousen/OpenAIClient增强库实战指南
  • 投资3000亿,日本汽车转向下一个与中国相当的市场,新的希望?
  • OrchardKit:现代Web应用UI组件库的设计哲学与工程实践
  • MarkLLM:基于结构化标记的PDF文档智能理解与问答框架
  • TUN3D:单张图像实现室内3D场景重建的技术解析
  • 麻烦不是来折磨你的,它是系统派来的“压力测试”
  • 用FLAC3D给断层“做CT”:从GOCAD几何模型到摩尔-库伦模拟的完整流程
  • Pravega监控与运维:关键指标和告警配置指南
  • SPICE框架:大模型自博弈训练提升推理能力
  • 避坑指南:Part-DB Docker部署时关于语言、时区和HTTPS的3个关键配置
  • IBM xSeries 450服务器Linux安装与优化指南
  • C++学生管理系统实战教程
  • 3分钟学会:BotW存档管理器让你的Switch与WiiU游戏进度无缝同步
  • 为什么你的.NET 9低代码组件无法通过.NET Native AOT?微软内部验证的4步编译兼容性诊断法
  • EventCalendar高级定制技巧:打造独一无二的企业级日历应用
  • ARM架构SVE与SME向量计算技术解析
  • ToolFlow:基于LLM的智能工作流编排框架,让AI从代码生成升级为流程工程师
  • Sequelize 与 TypeORM 在 Node.js 异步数据库操作上的性能对比
  • StyLua语言服务器模式:实现实时代码格式化与编辑器深度集成
  • Qwen2-VL-72B-Instruct开发者进阶:自定义视觉处理与模型微调
  • Vue3+java基于springboot框架的考研学生在线学习与交流系统的设计与实现
  • SocratiCode:从哲学思辨到代码清晰度的编程方法论实践
  • 0为什么不能作除数
  • RoPE启发的KV缓存压缩技术解析
  • 如何发布你的Fabric-example-mod:从本地测试到Maven仓库的完整流程
  • pbpython交互式应用开发:构建企业级数据仪表板的完整流程
  • Controlnet QR Code Monster v2与元宇宙结合:虚拟世界中的二维码应用
  • rk3568 nvme硬盘分区,格式化,挂载测试
  • 从零构建开源机械爪:STM32舵机控制与机电一体化实战
  • 告别桌面版臃肿!在Mac M1的VMware Fusion上极简安装CentOS 8 Server版并配置开发环境