简介

Generator函数是ES6提供的一种异步编程解决方案,最大的特点就是 : 可以交出函数的执行权 (即暂停执行)。

形式上 , Generator函数是一个普通函数 , 但是有两个特征 :

  1. function 关键字与函数名之间有一个 ( * )。
  2. 函数内部使用 yield 语句, 定义不同的内部状态。

定义及调用

  • 函数声明

ES6没有规定,function关键字与函数名之间的星号,写在哪个位置。这导致下面的写法都能通过。

     function * foo(x, y) { ··· }function *foo(x, y) { ··· }function* foo(x, y) { ··· }function*foo(x, y) { ··· }
复制代码
  • 函数表达式

       let foo = function * (){ ... }
    复制代码
  • 函数调用

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

下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从"函数头部或上一次停下来的地方"开始执行,直到遇到下一个yield语句(或return语句)为止。

     function * fn(){yield "one";yield "two";return "last";}let e = fn();console.log(e.next()); // {value: "one", done: false}console.log(e.next()); // {value: "two", done: false}console.log(e.next()); // {value: "last", done: true}console.log(e.next()); // {value: undefined, done: true}
复制代码

value属性表示当前的内部状态的值,是yield语句后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

yield 语句

yield语句就是暂停标志

遍历器对象的next方法的运行逻辑如下:

  1. 遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
  2. 下一次调用next方法时,再继续往下执行,直到遇到下一个yield语句。
  3. 如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。
  4. 如果该函数没有return语句,则返回的对象的value属性值为undefined。

注意 :

  • Generator函数可以不用yield语句,这时就变成了一个单纯的暂缓执行函数。

       function * fn(){console.log("hahaha")}let generator = fn();setTimeout(function(){generator.next()},2000)
    复制代码
  • yield语句不能用在普通函数中,否则会报错。

next方法的参数

yield句本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield语句的返回值。

注意了 : 是上一个yield 语句的返回值 , 这一点在循环中比较容易搞混。

     function* f() {for(var i=0; true; i++) {var reset = yield i;if(reset) { i = -1; }}}var g = f();g.next() // { value: 0, done: false }g.next() // { value: 1, done: false }g.next(true) // { value: 0, done: false }// 第三步的true会当做上一个yield语句的返回值 , 也就是说 i会先赋值为 -1 ,然后 i++ 变为 0 输出。
复制代码

for ... of 循环

for...of循环可以自动遍历Generator函数时生成的Iterator对象,且此时不再需要调用next方法。

     function *foo() {yield 1;yield 2;yield 3;yield 4;yield 5;return 6;}for (let v of foo()) {console.log(v);}// 1 2 3 4 5
复制代码

一旦next方法的返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象,所以上面代码的return语句返回的6,不包括在for...of循环之中。但是 , 若将 6 换为yield 则会输出 , 因为此时 done 为 false。

除了for...of循环以外,扩展运算符(...)、解构赋值和Array.from方法内部调用的,都是遍历器接口。这意味着,它们都可以将Generator函数返回的Iterator对象,作为参数。

     // 扩展运算符[...fn()] // [1,2,3,4,5]// Array.from() 方法Array.from(fn()) // [1,2,3,4,5]// 解构赋值let [x,y,z] = fn()// x 1 y 2 z3
复制代码

Generator.prototype.throw()

Generator函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后在Generator函数体内捕获。

     function * fn(){try {yield}catch(e){console.log('内部捕获',e.message)}}var i = fn()i.next() try{i.throw(new Error('你说你错了'))i.throw('不走心那')}catch(e){console.log("外部捕获",e)}// 内部捕获 你说你错了// 外部捕获 不走心那
复制代码

Generator.prototype.return()

Generator函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历Generator函数。

     function * fn(){yield 1;yield 2;yield 3;}let g = fn();console.log(g.next())  // {value: 1, done: false}console.log(g.return(10)) //{value: 10, done: true}console.log(g.next()) // {value: undefined, done: true}
复制代码

如果return方法调用时,不提供参数,则返回值的value属性为undefined。

yield*语句

如果在Generater函数内部,调用另一个Generator函数,默认情况下是没有效果的。 这个就需要用到yield*语句,用来在一个Generator函数里面执行另一个Generator函数。

     function* foo() {yield 'a';yield 'b';}function* bar() {yield 'x';foo();yield 'y';}function* bar() {yield 'x';yield* foo();yield 'y';}// "x"// "a"// "b"// "y"
复制代码

ES6 Generator 函数相关推荐

  1. [ES6] Generator 函数

    [ES6] Generator 函数 Generator 函数与普通函数的区别 执行机制 Generator 函数返回的遍历器对象的方法 循环遍历器 Iterator 对象的方法 next 方法 re ...

  2. es6 Generator函数的应用

    Generator函数的应用 es6 Generator 可以暂停函数执行,返回任意表达式的值.这种特点使得 Generator 有多种应用场景. 异步操作的同步化表达 Generator函数的暂停执 ...

  3. es6 Generator函数的含义

    Generator函数的含义 Generator 与状态机 Generator 是实现状态机的最佳结构.比如,下面的clock函数就是一个状态机. var ticking = true; var cl ...

  4. es6 Generator函数的this

    Generator函数的this Generator函数总是返回一个遍历器,ES6 规定这个遍历器是Generator函数的实例,也继承了Generator函数的prototype对象上的方法. fu ...

  5. es6 Generator函数概述

    概述 什么是Generator函数 Generator函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.本章详细介绍 Generator函数的语法和 API,它的异步编程应用请看 ...

  6. ES6——Generator 函数的语法

    Generator 函数是一个状态机,封装了多个内部状态.执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数.返回的遍历器对象 ...

  7. ES6 Generator函数

    一.基本概念 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同. Generator 函数有多种理解角度. 语法上,Generator 函数是一个状态机,封装 ...

  8. 理解 ES6 Generator 函数

    Generator函数是ES6引入的新型函数,用于异步编程,跟Promise对象联合使用的话会极大降低异步编程的编写难度和阅读难度. Generator函数跟普通函数的写法有非常大的区别: 一是,fu ...

  9. ES6 generator函数的详解

    迭代器的基础用法 function* helloGenerator(){yield '我是next1'yield '我是next2'return 123 } let res = helloGenera ...

  10. ES6 Generator函数 深入应用

    前提 线程与进程 在操作系统(此处说的系统是引入了线程概念的系统)中一个应用要想执行必须有一定的执行资源,而执行资源大致分为两个部分一个是执行时需要用的内存,一个是CPU执行权.而系统分配给每个应用的 ...

最新文章

  1. 大三Java后端暑期实习面经总结——Java多线程并发篇
  2. appium 启动失败解决方案
  3. QIIME 2用户文档. 20命令行界面q2cli(2019.7)
  4. WPF的Clipboard.SetText()有问题
  5. c++异常的层次结构(继承在异常中的应用)
  6. 开源数据访问组件Smark.Data 1.7新增功能
  7. Django(part20)--数据库和模型
  8. Linux 灾难恢复 Linux 系统启动故障修复
  9. loadrunner11完整卸载
  10. wxpython多线程_WxPython 4.0.4多线程访问UI
  11. 前端开发者常用的9个JavaScript图表库
  12. 【Redis笔记】简单动态字符串(SDS)
  13. WCF框架基础(一)
  14. jQuery笔记二——基础/动画
  15. 王通:网络营销人才必备的10种技能
  16. python遗传算法解决分配问题
  17. Android 完美高仿的微信源码(转载)
  18. 看拉扎维《模拟CMOS集成电路设计》的一些总结和思考(十)——稳定性与频率补偿
  19. RFID EPC Class1 Gen2电子标签笔记
  20. 计算机232接口接线图,串口线(232接口详细接线图)

热门文章

  1. mysql 手机归属地_盒子 - 手机归属地 MySql 数据
  2. updatepanel失效怎么办_[转]jquery与updatepanel二次失效问题解决方案-阿里云开发者社区...
  3. MacBook pro HTML 编写,老司机血泪劝告:买MacBook Pro一定不要买顶配!
  4. 如何保证战略落地_博雅视野丨大健康战略时代,全龄康养如何落地?
  5. centos llvm安装_CentOS7.x安装LLVM6.0
  6. docker基本镜像添加mysql_Docker的Centos7容器配置Tomcat和MySQL并打成基础镜像
  7. getdistance mysql_mysql 自定义函数获取两点间距离
  8. vscode代码编辑框控件_vscode编辑器的使用及插件
  9. 实现一个本地的json访问地址优化版本--python
  10. matlab全局变量_MATLAB笔记(一):工具箱的卸载、阻尼振动波形图程序