今天我们来学习ES6给我们带来的一种新函数,在学习它之前,前端君希望你已经阅读并初步了解了上一节的内容:iterator遍历器。因为本节的内容,是建立在iterator遍历器知识的基础上。

如果是新来的童鞋,或者您还未了解iterator遍历器,我希望你可以先学习上一节的内容,点击可查看:第十四节iterator遍历器的介绍。

既然你都看到这里来了,就咱们就接着往下讲...

声明Generator函数

我们要学习的这个新函数叫做:Generator函数,又称生成器函数,是ES6的一个重要的新特性。

我们来看看这个函数张什么模样:

    //声明一个Hello的Generator函数    function* Hello(name) {        yield `hello ${name}`;        yield `how are you`;        yield `bye`;    }

上面这个就是Generator函数,乍一看,是不是跟普通的函数没什么两样?确实很像,但是我们要知道它有两个重要的区别:

  1. 普通函数用function来声明,Generator函数用function*声明。

  2. Generator函数内部有新的关键字:yield,普通函数没有。

PS:函数体内用到了ES6的新特性:字符串模板。第六节的内容,点击可以查看。

了解了Generator函数的声明方式,我们又多了两个疑问:

  1. Generator函数运行起来会发生什么?

  2. 关键字yield语句的作用是什么?

调用Generator函数

带着这两个疑问我们往下看,我们试着就调用一下这个名字叫Hello的Generator函数,看看会发生什么:

    //声明一个Hello的Generator函数    function* Hello(name) {        yield `hello ${name}`;        yield `how are you`;        yield `bye`;    }

    //调用Hello函数    let ite = Hello('前端君');    //结果:[object Generator]

    ite.next();    //{value: "hello 前端君", done: false}

    ite.next();    //{value: "how are you", done: false}

    ite.next();    //{value: "bye", done: false}

    ite.next();    //{value: undefined, done: true}

看到这里,估计你也看到了一个熟悉的面孔:next()方法。(上一节iterator遍历器的内容)。

我们一起看看整个过程发生了什么:

一开始,我们调用Hello(“前端君”),函数执行后,返回了一个:[object Genrator]生成器对象,我们把它赋值到变量ite中,仅此而已,并没有做太多的事情。

接着,第1次调用生成器对象ite的next( )方法,返回了一个对象:

    {value: "hello 前端君", done: false}

第2次调用生成器对象ite的next( )方法,同样得到了一个对象:

    {value: "how are you", done: false}

第3次调用生成器对象ite的next( )方法,又得到了一个对象:

    {value: "bye", done: false}

直到,第4次调用生成器对象ite的next( )方法,返回的对象:

    {value: undefined, done: true}

看到这里有没有发现,这里生成器的next( )方法的和遍历器iterator的next( )方法的返回结果是不是一样?

没错,你可以把Generator函数被调用后得到的生成器理解成一个遍历器iterator,用于遍历函数内部的状态。(所以要求大家先学习第十三节iterator遍历器的知识)

Generator函数的行为

通过上面的案例,我们知道了:Generator函数被调用后并不会一直执行到最后,它是先回返回一个生成器对象,然后hold住不动,等到生成器对象的next( )方法被调用后,函数才会继续执行,直到遇到关键字yield后,又会停止执行,并返回一个Object对象,然后继续等待,直到next( )再一次被调用的时候,才会继续接着往下执行,直到done的值为true。

yield语句的作用

而yield在这里起到了十分重要的作用,就相当于暂停执行并且返回信息。有点像传统函数的return的作用,但不同的是普通函数只能return一次,但是Generator函数可以有很多个yield。而return代表的是终止执行,yield代表的是暂停执行,后续通过调用生成器的next( )方法,可以恢复执行

next( )方法接收参数

此外,next( )方法还可以接受一个参数,它的参数会作为上一个yield的返回值,我们来看一下:

    //声明一个Hello的Generator函数    function* Hello() {        let res = yield `hello`;        yield res;    }

    let iterator = Hello();    //结果:一个生成器对象

    iterator.next();    //结果:{value: "hello", done: false}

    iterator.next("前端君");    //结果:{value: "前端君", done: false}

注意函数体内的第一个yield关键字,我们把它的返回值赋值给了一个变量res。

再看2次next方法的调用:

第1次调用next( )方法,返回的对象属性value值为“hello”,属性done值为:fasle,并暂停执行。

第2次next( )方法,传入参数:字符串“前端君”。此时,第二个yield关键字紧跟着的是变量res,而变量res的值正是上一个关键字yield的返回值。也就是说这个值正是我们传入的参数:“前端君”。因为:next( )的参数会作为上一个yield的返回值。

慢慢体会一下,理清逻辑,稍微有点绕。

关键字yield*

在一个Generator函数里面,如果我们想调用另一个Generator函数,就需要用到的关键字是:yield*。

我们来看看怎么玩,代码有点长,但是很好理解:

    //声明Generator函数:gen1       function* gen1() {        yield "gen1 start";        yield "gen1 end";    }

    //声明Generator函数:gen2    function* gen2() {        yield "gen2 start";        yield "gen2 end";    }

    //声明Generator函数:start    function* start() {        yield "start";        yield* gen1();        yield* gen2();        yield "end";    }

    //调用start函数    var ite = start();    //创建一个生成器

    ite.next();    //{value: "start", done: false}

    ite.next();    //{value: "gen1 start", done: false}

    ite.next();    //{value: "gen1 end", done: false}

    ite.next();    //{value: "gen2 start", done: false}

    ite.next();    //{value: "gen2 end", done: false}

    ite.next();    //{value: "end", done: false}

我们主要看start( )这个Generator函数,其中有两句代码:

    yield* gen1();    yield* gen2();

这里使用了关键字yield*来实现调用另外两个Generator函数。从后面的多个next( )方法得到的结果看,我们可以知道:

 如果一个Generator函数A执行过程中,进入(调用)了另一个Generator函数B,那么会一直等到Generator函数B全部执行完毕后,才会返回Generator函数A继续执行。

Generator函数的用途

以上就是对Generator函数的讲解介绍,它是ES6的一个很重要的新特性。它可以控制函数的内部状态,依次遍历每个状态;可以根据需要,轻松地让函数暂停执行或者继续执行。

根据这个特点,我们可以利用Generator函数来实现异步操作的效果。

原理是:利用Generator函数暂停执行的作用,可以将异步操作的语句写到yield后面,通过执行next方法进行回调。

本节小结

总结:Generator函数是一种特殊的函数,可以使用关键字yield和next( )实现暂停和继续执行,而关键字yield*专门用于调用Generator函数,看似简单的特性,在实际开发中却有极大的用处。

第十五节:有一种特殊的函数叫:Generator函数相关推荐

  1. 第三百二十五节,web爬虫,scrapy模块标签选择器下载图片,以及正则匹配标签...

    第三百二十五节,web爬虫,scrapy模块标签选择器下载图片,以及正则匹配标签 标签选择器对象 HtmlXPathSelector()创建标签选择器对象,参数接收response回调的html对象 ...

  2. Python编程基础:第五十五节 map函数Map

    第五十五节 map函数Map 前言 实践 前言 map函数的作用是将指定函数作用于一个可迭代对象内部的每一个元素,其表达方式为map(function, iterable),第一个位置指定作用函数,第 ...

  3. Python编程基础:第四十五节 方法链Method Chaining

    第四十五节 方法链Method Chaining 前言 实践 前言 方法链是指一个对象一次调用其自身的多个方法,通常写作对象.方法1.方法2.由于这种调用方法看起来像一个链条,所以我们将其称作方法链. ...

  4. Python编程基础:第三十五节 文件删除Delete a File

    第三十五节 文件删除Delete a File 前言 实践 前言 我们这一节来介绍如何删除一个文件,这里需要用到函数os.remove(path)用于删除指定路径下的文件,os.rmdir(path) ...

  5. Python编程基础:第二十五节 args参数*args

    第二十五节 args参数*args 前言 实践 前言 我们目前学习到的函数的参数个数都是固定的,那么我们是否可以指定任意多个参数呢?其实是可以的,这里就用到了args参数,它可以将用户指定的任意多个参 ...

  6. Python编程基础:第十五节 二维列表2D Lists

    第十五节 二维列表2D Lists 前言 实践 前言 列表中的元素可以是任何形式,整型.浮点型.字符串型,甚至是一个列表.当列表的元素也是列表时,我们将其称为二维列表. 实践 我们先来创建多个一维列表 ...

  7. 第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图...

    第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲-爬虫和反爬的对抗过程以及策略-scrapy架构源码分析图 1.基本概念 2.反爬虫的目的 3.爬虫和反爬的对抗过程以及策略 scra ...

  8. 我的世界服务器群系修改,我的世界创世神教程 第五十五节修改选区的生物群系|功能介绍|难点介绍|这节...

    我的世界WorldEdit创世神高级系列教程 第五十五节修改选区的生物群系.本教程由64条不同的技巧,功能介绍,难点介绍,防范措施介绍,工具介绍等组成.适合高级玩家和腐竹们来学习.这节内容给大家介绍修 ...

  9. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十五节: 3D项目优化方案

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第二十五节:3D项目优化方案 视频地址:http://edu.csdn.net/course/detail/1330/20825?au ...

最新文章

  1. Android APP开发
  2. js函数 every some map ()=a+b;
  3. 29. 栈的push,pop序列
  4. 关于ViewPager的适配器之——pagerAdapter加载缓存页面的机制
  5. 基于VMWare配置VxWorks开发环境
  6. 华为OV小米鸿蒙,华为鸿蒙开源,小米OV们会采用吗?
  7. python print 输出到txt_(Python基础教程之七)Python字符串操作
  8. 计算机 未来哪种技术稀缺,2015级职业生涯规划考试试题
  9. Python面向对象编程 self的含义
  10. 将JQuery框架集成到SharePoint 2010中
  11. GEE学习笔记4:Sentinel 2 植被指数计算
  12. gdown配置代理下载Google drive文件
  13. 柴静穹顶之下 感想
  14. 动画七、动画的PropertyValuesHolder与Keyframe
  15. wget 无法验证某某颁发的证书
  16. 全面提高影像科图像质量(二)——CT板块
  17. ABAP SY-系统值
  18. IT行业常用网站与平台汇总(持续更新...)
  19. 树莓派连接使用5寸HDMI触摸屏的方法
  20. Webpack中的文件指纹

热门文章

  1. 2020年抖音创作者生态报告
  2. 编写程序,定义一个方法,能够判断一个1~9999之间的数是否是回文数。
  3. php生成网页缩略图接口,php生成网站缩略图
  4. 天津科技大学计算机基础,天津科技大学大学计算机基础样卷
  5. 【2016年第5期】数据科学人才的需求与培养
  6. 作者:朱扬勇,博士,复旦大学计算机科学技术学院教授、学术委员会主任,上海市数据科学重点实验室主任。...
  7. 【面向对象】聚合的四种语义
  8. 【计算机网络】关键词汇翻译整合
  9. 【计算机网络】FDM和TDM的传输总时间计算
  10. 在VS 2010上搭建Windows Phone 7开发平台