ES6 Generator 函数
简介
Generator函数是ES6提供的一种异步编程解决方案,最大的特点就是 : 可以交出函数的执行权 (即暂停执行)。
形式上 , Generator函数是一个普通函数 , 但是有两个特征 :
- function 关键字与函数名之间有一个 ( * )。
- 函数内部使用 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方法的运行逻辑如下:
- 遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
- 下一次调用next方法时,再继续往下执行,直到遇到下一个yield语句。
- 如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。
- 如果该函数没有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 函数相关推荐
- [ES6] Generator 函数
[ES6] Generator 函数 Generator 函数与普通函数的区别 执行机制 Generator 函数返回的遍历器对象的方法 循环遍历器 Iterator 对象的方法 next 方法 re ...
- es6 Generator函数的应用
Generator函数的应用 es6 Generator 可以暂停函数执行,返回任意表达式的值.这种特点使得 Generator 有多种应用场景. 异步操作的同步化表达 Generator函数的暂停执 ...
- es6 Generator函数的含义
Generator函数的含义 Generator 与状态机 Generator 是实现状态机的最佳结构.比如,下面的clock函数就是一个状态机. var ticking = true; var cl ...
- es6 Generator函数的this
Generator函数的this Generator函数总是返回一个遍历器,ES6 规定这个遍历器是Generator函数的实例,也继承了Generator函数的prototype对象上的方法. fu ...
- es6 Generator函数概述
概述 什么是Generator函数 Generator函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.本章详细介绍 Generator函数的语法和 API,它的异步编程应用请看 ...
- ES6——Generator 函数的语法
Generator 函数是一个状态机,封装了多个内部状态.执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数.返回的遍历器对象 ...
- ES6 Generator函数
一.基本概念 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同. Generator 函数有多种理解角度. 语法上,Generator 函数是一个状态机,封装 ...
- 理解 ES6 Generator 函数
Generator函数是ES6引入的新型函数,用于异步编程,跟Promise对象联合使用的话会极大降低异步编程的编写难度和阅读难度. Generator函数跟普通函数的写法有非常大的区别: 一是,fu ...
- ES6 generator函数的详解
迭代器的基础用法 function* helloGenerator(){yield '我是next1'yield '我是next2'return 123 } let res = helloGenera ...
- ES6 Generator函数 深入应用
前提 线程与进程 在操作系统(此处说的系统是引入了线程概念的系统)中一个应用要想执行必须有一定的执行资源,而执行资源大致分为两个部分一个是执行时需要用的内存,一个是CPU执行权.而系统分配给每个应用的 ...
最新文章
- 大三Java后端暑期实习面经总结——Java多线程并发篇
- appium 启动失败解决方案
- QIIME 2用户文档. 20命令行界面q2cli(2019.7)
- WPF的Clipboard.SetText()有问题
- c++异常的层次结构(继承在异常中的应用)
- 开源数据访问组件Smark.Data 1.7新增功能
- Django(part20)--数据库和模型
- Linux 灾难恢复 Linux 系统启动故障修复
- loadrunner11完整卸载
- wxpython多线程_WxPython 4.0.4多线程访问UI
- 前端开发者常用的9个JavaScript图表库
- 【Redis笔记】简单动态字符串(SDS)
- WCF框架基础(一)
- jQuery笔记二——基础/动画
- 王通:网络营销人才必备的10种技能
- python遗传算法解决分配问题
- Android 完美高仿的微信源码(转载)
- 看拉扎维《模拟CMOS集成电路设计》的一些总结和思考(十)——稳定性与频率补偿
- RFID EPC Class1 Gen2电子标签笔记
- 计算机232接口接线图,串口线(232接口详细接线图)
热门文章
- mysql 手机归属地_盒子 - 手机归属地 MySql 数据
- updatepanel失效怎么办_[转]jquery与updatepanel二次失效问题解决方案-阿里云开发者社区...
- MacBook pro HTML 编写,老司机血泪劝告:买MacBook Pro一定不要买顶配!
- 如何保证战略落地_博雅视野丨大健康战略时代,全龄康养如何落地?
- centos llvm安装_CentOS7.x安装LLVM6.0
- docker基本镜像添加mysql_Docker的Centos7容器配置Tomcat和MySQL并打成基础镜像
- getdistance mysql_mysql 自定义函数获取两点间距离
- vscode代码编辑框控件_vscode编辑器的使用及插件
- 实现一个本地的json访问地址优化版本--python
- matlab全局变量_MATLAB笔记(一):工具箱的卸载、阻尼振动波形图程序