Javascript的生成器函数是什么_如何用于异步编程?

发布时间 - 2025-12-27 00:00:00    点击率:
生成器函数是用 function* 声明的特殊函数,调用后返回迭代器对象,通过 next() 暂停/恢复执行并 yield 值;可配合 Promise 和执行器模拟 async/await 风格异步流程,但现已被原生 async/await 取代,多用于自定义迭代或框架底层(如 Redux-Saga)。

生成器函数是 JavaScript 中一种特殊的函数,它能暂停和恢复执行,配合 yield 关键字产出值。它本身不直接处理异步,但通过与 Promise、async/await 或自定义执行器协作,可构建出类似同步风格的异步流程。

生成器函数的基本特征

function* 声明,调用后返回一个迭代器对象(不是执行函数体),每次调用 next() 才运行到下一个 yield 并暂停。返回值是 { value, done } 形式的对象。

例如:

function* countdown(n) {
  while (n > 0) {
    yield n;
    n--;
  }
}

const it = countdown(3);
it.next(); // { value: 3, done: false }
it.next(); // { value: 2, done: false }
it.next(); // { value: 1, done: false }
it.next(); // { value: undefined, done: true }

用生成器模拟 async/await 风格的异步流程

核心思路是:让生成器 yield 一个 Promise,外部执行器捕获该 Promise,等它 resolve 后再用 next(value) 把结果传回生成器继续执行。

  • 生成器内部写法接近同步:不用嵌套 .then,也不显式写 await(但语义类似)
  • 需要手动或借助库(如 co)驱动执行,即反复调用 next() 并处理 Promise
  • 错误可通过 it.throw(err) 注入生成器内部,配合 try/catch 捕获

简易执行器示例:

function run(genFn) {
  const it = genFn();
  function next(val) {
    const { value, done } = it.next(val);
    if (done) return value;
    if (value instanceof Promise) {
      return value.then(next).catch(err => it.throw(err));
    } else {
      return next(value);
    }
  }
  return next();
}

// 使用:
run(function* () {
  const user = yield fetch('/api/user').then(r => r.json());
  console.log(user.name);
  const posts = yield fetch(`/api/posts?uid=${user.id}`).then(r => r.json());
  return posts;
});

与现代 async/await 的关系

生成器曾是实现协程式异步的主流方案(尤其在 async/await 出现前),但现在已被原生 async/await 取代:

  • async/await 语法更简洁,错误处理更自然,引擎级优化更好
  • 生成器现在更多用于需精细控制迭代逻辑的场景(如惰性序列、状态机、遍历树结构)
  • 少数库仍基于生成器实现高级控制流(如 Redux-Saga 中的 takeEverycall 等 effect)

实际建议

日常开发中无需主动用生成器写异步逻辑:

  • 优先使用 async/await —— 语义清晰、调试友好、浏览器支持完善
  • 理解生成器原理有助于读懂老项目或特定框架(如 Saga)的源码
  • 若需自定义迭代行为(比如分页拉取、无限滚动的数据流),生成器 + yield 是天然选择


# javascript  # java  # js  # json  # 浏览器  # ai  # red 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  如何快速登录WAP自助建站平台?  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  Python结构化数据采集_字段抽取解析【教程】  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  Laravel如何使用Sanctum进行API认证?(SPA实战)  如何在阿里云高效完成企业建站全流程?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  如何确保西部建站助手FTP传输的安全性?  如何用景安虚拟主机手机版绑定域名建站?  C语言设计一个闪闪的圣诞树  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  JavaScript数据类型有哪些_如何准确判断一个变量的类型  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  Laravel如何实现模型的全局作用域?(Global Scope示例)  想要更高端的建设网站,这些原则一定要坚持!  laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法  JavaScript常见的五种数组去重的方式  Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】  Android使用GridView实现日历的简单功能  网站图片在线制作软件,怎么在图片上做链接?  如何在建站之星网店版论坛获取技术支持?  EditPlus中的正则表达式 实战(2)  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用  如何在景安云服务器上绑定域名并配置虚拟主机?  教你用AI将一段旋律扩展成一首完整的曲子  如何选择可靠的免备案建站服务器?  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  PHP 500报错的快速解决方法  如何在万网利用已有域名快速建站?  ,南京靠谱的征婚网站?  Laravel怎么使用artisan命令缓存配置和视图  Laravel如何配置任务调度?(Cron Job示例)  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  Laravel如何使用Telescope进行调试?(安装和使用教程)  javascript中闭包概念与用法深入理解  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  装修招标网站设计制作流程,装修招标流程?  浅述节点的创建及常见功能的实现  HTML 中动态设置元素 name 属性的正确语法详解  php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率