Javascript生成器(Generator)的介绍与使用


Posted in Javascript onJanuary 31, 2021

什么是生成器?

生成器是在函数内部运行的一些代码

  • 返回值后,它会自行暂停,并且——
  • 调用程序可以要求取消暂停并返回另一个值

这种“返回”不是传统的从函数 return。所以它被赋予了一个特殊的名称——yield。

生成器语法因语言而异。Javascript 的生成器语法类似于 PHP,但是区别也很大,如果你希望它们的作用相同,那么最终你会感到非常困惑。

在 javascript 中,如果想要使用生成器,则需要:

  • 定义特殊的生成器函数
  • 调用该函数创建一个生成器对象
  • 在循环中使用该生成器对象,或直接调用其 next 方法

我们以下面这个简单的程序做为起点,并执行以下每个步骤:

// File: sample-program.js
function *createGenerator() {
 for(let i=0;i<20;i++) {
 yield i
 }
}

const generator = createGenerator()

console.log(generator.next())
console.log(generator.next())

如果运行这段代码,则会得到以下输出:

$ node sample-program.js

{ value: 0, done: false }
{ value: 1, done: false }

下面我来解释该程序是如何工作的。

生成器函数

首先,代码中存在生成器函数的定义:

function* createGenerator() {
 for(let i=0;i<20;i++) {
 yield i
 }
}

function 后面的 * 告诉 javascript 这是一个生成器函数。以下写法都是生成器函数的有效定义。

function*createGenerator
function* createGenerator
function *createGenerator

*  并不是函数名的一部分。而是 function* 符号定义了生成器。

调用生成器函数

定义了生成器函数后,我们将其命名为其他名称的函数。

// 注意:当调用时,没有 *。 * 不是函数名称的一部分
// `function *` 是用于定义生成器函数的符号
const generator = createGenerator()

但是要记住:createGenerator 函数没有返回值。这是因为生成器函数没有传统的返回值。相反,当你直接调用生成器函数时,它总是返回实例化的 Generator 对象。

这个生成器对象具有一个 next 方法。调用 next 将在生成器函数内部运行代码。

function* createGenerator() {
 for(let i=0;i<20;i++) {
  yield i
 }
}

这很重要,足以再次调用它。直接调用生成器函数不会在生成器函数中运行任何代码。而是创建一个生成器对象。它在生成器对象上调用 next,从而调用生成器函数中的代码。

首次在生成器对象上调用 next 时,内部代码将会一直运行,直到出现 yield 语句。一旦执行到 yield,javascript 将会暂停该代码的执行,而 next 将返回(即给你,或yield)一个对象,该对象包含 yield 行中的值。

当你第二次(或第三次、第四次甚至更多次)再调用 next 时,代码将会取消暂停并继续运行(在上次调用时中断的地方)。变量(例如本例中的 i )将会保持它的值。当代码到达另一个 yield 语句时,该函数会再次暂停,并返回一个包含 yield 值的对象。

这就是为什么我们要调用两次  next

console.log(generator.next())
console.log(generator.next())

会得到以下输出:

{ value: 0, done: false }
{ value: 1, done: false }

生成器函数中的代码执行完毕后,将来对 next 的任何调用都会返回一个对象,该对象的值为 undefined 且done 设置为 true。

{ value: undefined, done: true }

生成器和循环

虽然可以在生成器对象上手动调用 next,但我们主要是要在循环中使用。看一下这个稍作修改的程序。

// File: sample-program.js
@highlightsyntax@jscript
function *createGenerator() {
 for(let i=0;i<5;i++) {
 yield i
 }
}

const generator = createGenerator()
for(const value of generator) {
 console.log(value)
}

当在 for...of 循环中使用生成器对象时,每次循环都会在生成器对象上调用 next,并用产生的值填充变量(上面的 value)。运行该程序将会输出以下内容:

$ node sample-program.js
0
1
2
3
4

在下一篇文章中,我们将更深入地探讨 for ... of 循环,并探索怎样为 javascript 提供一种内置方法来循环 javascript 中的任何对象。

总结

到此这篇关于Javascript生成器(Generator)的文章就介绍到这了,更多相关Javascript生成器(Generator)内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jquery右下角弹出提示框示例代码
Oct 08 Javascript
浅谈toLowerCase和toLocaleLowerCase的区别
Aug 15 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
Sep 09 Javascript
详解在 Angular 项目中添加 clean-blog 模板
Jul 04 Javascript
Koa日志中间件封装开发详解
Mar 09 Javascript
js逆向解密之网络爬虫
May 30 Javascript
vue+eslint+vscode配置教程
Aug 09 Javascript
layui监听单元格编辑前后交互的例子
Sep 16 Javascript
详解Vue.js 响应接口
Jul 04 Javascript
Jquery如何使用animation动画效果改变背景色的代码
Jul 20 jQuery
vue+高德地图实现地图搜索及点击定位操作
Sep 09 Javascript
vue实践---根据不同环境,自动转换请求的url地址操作
Sep 21 Javascript
Node.js中的异步生成器与异步迭代详解
Jan 31 #Javascript
Vite和Vue CLI的优劣
Jan 30 #Vue.js
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 #Vue.js
Element-ui 自带的两种远程搜索(模糊查询)用法讲解
Jan 29 #Javascript
小程序实现列表倒计时功能
Jan 29 #Javascript
JS相册图片抖动放大展示效果的示例代码
Jan 29 #Javascript
vue监听键盘事件的相关总结
Jan 29 #Vue.js
You might like
萌王史莱姆”萌王性别尴尬!那“萌战”归女组还是男?
2018/12/17 日漫
预告映像公开!第1章续篇剧场版动画《Princess Principal Crown Handler》4月10日上映!
2020/03/06 日漫
PHP实现上传多图即时显示与即时删除的方法
2017/05/09 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
2010/09/14 Javascript
基于Jquery与WebMethod投票功能实现代码
2011/01/19 Javascript
在JavaScript里嵌入大量字符串常量的实现方法
2013/07/07 Javascript
如何用jquery控制表格奇偶行及活动行颜色
2014/04/20 Javascript
你所不了解的javascript操作DOM的细节知识点(一)
2015/06/17 Javascript
关于foreach循环中遇到的问题小结
2017/05/08 Javascript
React-router中结合webpack实现按需加载实例
2017/05/25 Javascript
webpack实现热更新(实施同步刷新)
2017/07/28 Javascript
AngularJs导出数据到Excel的示例代码
2017/08/11 Javascript
vue技术分享之你可能不知道的7个秘密
2018/04/09 Javascript
Vue.js实现的表格增加删除demo示例
2018/05/22 Javascript
vue-cli3全面配置详解
2018/11/14 Javascript
在小程序中推送模板消息的实现方法
2019/07/22 Javascript
浅谈javascript错误处理
2019/08/11 Javascript
Vue优化:常见会导致内存泄漏问题及优化详解
2020/08/04 Javascript
[00:32]2018DOTA2亚洲邀请赛VG出场
2018/04/03 DOTA
windows系统中python使用rar命令压缩多个文件夹示例
2014/05/06 Python
Python程序设计入门(4)模块和包
2014/06/16 Python
python利用sklearn包编写决策树源代码
2017/12/21 Python
Django集成搜索引擎Elasticserach的方法示例
2019/06/04 Python
使用python实现男神女神颜值打分系统(推荐)
2019/10/31 Python
Python实现把类当做字典来访问
2019/12/16 Python
使用TensorBoard进行超参数优化的实现
2020/07/06 Python
澳大利亚香水在线商店:City Perfume
2020/09/02 全球购物
农贸市场管理制度
2014/01/31 职场文书
学习自我鉴定
2014/02/01 职场文书
技能竞赛活动方案
2014/02/21 职场文书
意向协议书范本
2014/04/23 职场文书
预防煤气中毒方案
2014/06/16 职场文书
化工专业求职信
2014/07/01 职场文书
2015新生加入学生会自荐书
2015/03/24 职场文书
2015年店长个人工作总结
2015/10/23 职场文书