资讯专栏INFORMATION COLUMN

Node v4 - Generator函数

cnTomato / 607人阅读

摘要:返回的遍历器对象,可以依次遍历函数内部的每一个状态。方法调用遍历器对象的方法,使得指针移向下一个状态。运行结果就是使用一个遍历器,遍历了多个函数,有递归的效果。

1、Generator简介

基本概念

Generator函数有多种理解角度。从语法上,首先可以把它理解成,Generator函数是一个状态机,封装了多个内部状态。

执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。

形式上,Generator函数是一个普通函数,但是有两个特征。一是,function命令与函数名之间有一个星号;二是,函数体内部使用yield语句,定义不同的内部状态(yield语句在英语里的意思就是“产出”)。

"use strict";
function * helloWorldGenerator() {
    yield "hello";
    yield "world";
    return "ending";
}
let hw = helloWorldGenerator();

上面代码定义了一个Generator函数helloWorldGenerator,它内部有两个yield语句“hello”“world”,即该函数有三个状态:helloworldreturn语句(结束执行)。

然后,Generator函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用Generator函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,遍历器对象(Iterator Object)。

2、next方法

调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。换言之,Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。

hw.next()
// { value: "hello", done: false }
hw.next()
// { value: "world", done: false }
hw.next()
// { value: "ending", done: true }
hw.next()
// { value: undefined, done: true }

上面代码一共调用了四次next方法。

第一次调用,Generator函数开始执行,直到遇到第一个yield语句为止。next方法返回一个对象,它的value属性就是当前yield语句的值hellodone属性的值false,表示遍历还没有结束。

第二次调用,Generator函数从上次yield语句停下的地方,一直执行到下一个yield语句。next方法返回的对象的value属性就是当前yield语句的值worlddone属性的值false,表示遍历还没有结束。

第三次调用,Generator函数从上次yield语句停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。

第四次调用,此时Generator函数已经运行完毕,next方法返回对象的value属性为undefineddone属性为true。以后再调用next方法,返回的都是这个值。

总结一下,调用Generator函数,返回一个遍历器对象,代表Generator函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着valuedone两个属性的对象。value属性表示当前的内部状态的值,是yield语句后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

3、yield*语句

用来在一个Generator函数里面执行另一个Generator函数,我们需要用yield*语句。

如果yield命令后面跟的是一个遍历器对象,需要在yield命令后面加上星号,表明它返回的是一个遍历器对象。这被称为yield*语句。

"use strict";
function *anotherGenerator(i) {
    yield i + 1;
    yield i + 2;
    yield i + 3;
}
function *generator(i) {
    yield i;
    yield *anotherGenerator(i);
    yield i + 10;
}
let gen = generator(10);
console.log(gen.next().value);//10
console.log(gen.next().value);//11
console.log(gen.next().value);//12
console.log(gen.next().value);//13
console.log(gen.next().value);//20
console.log(gen.next().value);//undefined

运行结果就是使用一个遍历器,遍历了多个Generator函数,有递归的效果。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83639.html

相关文章

  • 【重温基础】13.迭代器和生成器

    摘要:迭代器和生成器将迭代的概念直接带入核心语言,并提供一种机制来自定义循环的行为。本文主要会介绍中新增的迭代器和生成器。属性本身是函数,是当前数据结构默认的迭代器生成函数。 本文是 重温基础 系列文章的第十三篇。今日感受:每次自我年终总结,都会有各种情绪和收获。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】1.语法和数据类型 【重温基础】2.流...

    ymyang 评论0 收藏0
  • 【HEXO】从零搭建HEXO博客 修改默认主题/参数/favicon 替换个人主页

    摘要:下面我以主题举例,覆盖默认主题。其他元素使用相同的方法都可以修改。像这种超链接跳转的修改,在文件中找到直接把属性的值改变即可。 准备:搭建环境 大致分为以下两步: 安装Node.js 安装git 配置Node.js环境 下载Node.js安装 Windows Installer 32-bithttps://nodejs.org/dist/v4.2.3/node-v4.2.3-x...

    My_Oh_My 评论0 收藏0
  • 【HEXO】从零搭建HEXO博客 修改默认主题/参数/favicon 替换个人主页

    摘要:下面我以主题举例,覆盖默认主题。其他元素使用相同的方法都可以修改。像这种超链接跳转的修改,在文件中找到直接把属性的值改变即可。 准备:搭建环境 大致分为以下两步: 安装Node.js 安装git 配置Node.js环境 下载Node.js安装 Windows Installer 32-bithttps://nodejs.org/dist/v4.2.3/node-v4.2.3-x...

    Near_Li 评论0 收藏0
  • 开始学习koa

    摘要:对已经跃跃欲试很久,恰遇最近正式发布,今天尝试着倒腾一番。所以自己对的学习算是从开始,由于文档资源还不完全,准备踩着前辈们的肩膀,慢慢入坑。常识入门级程序与大部分程序员同胞一样样的习惯,写一发慰藉自己孤寂的心灵。 对koa已经跃跃欲试很久,恰遇koa2最近正式发布,今天尝试着倒腾一番。所以自己对koa的学习算是从2.x开始,由于文档资源还不完全,准备踩着前辈们的肩膀,慢慢入坑。 环境的...

    KunMinX 评论0 收藏0
  • eslint V4.1.1 规则简介

    摘要:规则简介花了一天整理的,可能部分翻译的有错误,后面会再校对一次规则说明默认情况下不会启用任何规则。 eslint V4.1.1 规则简介 花了一天整理的,可能部分翻译的有错误,后面会再校对一次 规则说明:默认情况下不会启用任何规则。配置文件中的extends:eslint:recommended属性可以启用一些默认的验证规则,默认的规则在下表会用R表示出来 使用--fix命令可以自动修...

    tuomao 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<