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 相关文章推荐
几个高效,简洁的字符处理函数
Apr 12 Javascript
javascript的trim,ltrim,rtrim自定义函数
Sep 21 Javascript
js获取IP和PcName(IE)在vs中可用
Aug 02 Javascript
js向上无缝滚动,网站公告效果 具体代码
Nov 18 Javascript
JS连连看源码完美注释版(推荐)
Dec 09 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
Sep 21 Javascript
jQuery图片瀑布流的简单实现代码
Mar 15 Javascript
jQuery中用on绑定事件时需注意的事项
Mar 19 Javascript
layui动态绑定事件的方法
Sep 20 Javascript
浅谈Vue 自动化部署打包上线
Jun 14 Javascript
vue+element实现图片上传及裁剪功能
Jun 29 Javascript
深入详解JS函数的柯里化
Jun 09 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
使用数据库保存session的方法
2006/10/09 PHP
php递归使用示例(php递归函数)
2014/02/14 PHP
PHP 配置后台登录以及模板引入
2017/01/24 PHP
javascript插入样式实现代码
2012/02/22 Javascript
javascript学习笔记(五)原型和原型链详解
2014/10/08 Javascript
js实现获取div坐标的方法
2015/11/16 Javascript
javascript Slip.js实现整屏滑动的手机网页
2015/11/25 Javascript
任意Json转成无序列表的方法示例
2016/12/09 Javascript
一次围绕setTimeout的前端面试经验分享
2017/06/15 Javascript
element el-input directive数字进行控制
2018/10/11 Javascript
[01:32]TI奖金增速竟因它再创新高!DOTA2勇士令状不朽珍藏Ⅰ饰品欣赏
2018/05/18 DOTA
[01:04]不如跳舞!DOTA2新英雄玛尔斯的欢乐日常
2019/03/11 DOTA
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
Python之虚拟环境virtualenv,pipreqs生成项目依赖第三方包的方法
2019/07/23 Python
一文弄懂Pytorch的DataLoader, DataSet, Sampler之间的关系
2020/07/03 Python
HTML5新增form控件和表单属性实例代码详解
2019/05/15 HTML / CSS
美国高街时尚品牌:OASAP
2016/07/24 全球购物
俄罗斯和世界各地的酒店预订:Hotels.com俄罗斯
2016/08/19 全球购物
全球知名鞋履品牌授权零售商:Journeys
2016/09/17 全球购物
一家专门经营包包的英国网站:MyBag
2019/09/08 全球购物
全球领先的中国制造商品在线批发平台:DHgate
2020/01/28 全球购物
报到证丢失证明
2014/01/11 职场文书
运动会广播稿500字
2014/01/28 职场文书
优秀教师事迹简介
2014/02/02 职场文书
抽奖活动主持词
2014/03/31 职场文书
保险公司开门红口号
2014/06/21 职场文书
医德医魂心得体会
2014/09/11 职场文书
2014年财政所工作总结
2014/11/22 职场文书
高中生综合素质自我评价
2015/03/06 职场文书
车间统计员岗位职责
2015/04/14 职场文书
2015年酒店工作总结
2015/04/28 职场文书
2019秋季运动会口号
2019/06/25 职场文书
新手入门Jvm-- JVM对象创建与内存分配机制
2021/06/18 Java/Android
tp5使用layui实现多个图片上传(带附件选择)的方法实例
2021/11/17 PHP
教你使用VS Code的MySQL扩展管理数据库的方法
2022/01/22 MySQL
微信小程序APP页面的之间的相互传递参数以及自定义组件
2022/04/19 Javascript