ES6中Generator函数
1.Generator介绍
声明:Generator函数是ES6提供的一种异步编程的解决方案,可以看成一个状态机,封装了多个内部状态,执行Generator函数会返回一个遍历器对象,所以也是遍历器对象生成函数。 Generator函数也是一个普通函数,但是有两个特征。第一是funtction关键字与函数名之间有个*,第二是函数体内部使用yield表达式,定义不同的内部状态。
function* fun() {yield "张三" //状态1yield "李四" //状态2return "结束" //状态3}const obj = fun()console.log(obj); //fun {<suspended>}
声明: 返回的是一个指向内部状态的指针对象,也就是遍历器对象。
2.Generator 函数是分段执行
声明:Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。
console.log(obj.next()); //{value: '张三', done: false}console.log(obj.next()); //{value: '李四', done: false}console.log(obj.next()); //{value: '结束', done: true}// 第三次调用Generator函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。如果有retrun就执行到retrunconsole.log(obj.next()); //{value: undefined, done: true}
3. yield表达式
声明:一种可以暂停函数的标志的表达式,只有调用next()方法,内部指针指向该语句才执行。我们可以看成一种惰性求值的语法功能。
function* fun2(a, b) {yield a + breturn a * 5}const obj2 = fun2(5, 6)console.log(obj2); //fun2 {<suspended>}console.log(obj2.next()); //{value: 11, done: false}console.log(obj2.next()); //{value: 25, done: true}console.log(obj2.return(5)); //{value: 5, done: true}
注意:return与yield区别,一个函数里面只能有一个return语句。
4.特殊形式
说明:Genrator函数可以不用yield表达式,这时就变成了一个单纯的暂缓执行函数。
function* fun3() {console.log("Hello world");}console.log(fun3().next());//Hello world//{value: undefined, done: true}
5.yield表达注意点
- yield表达式,只能在Generator函数里面。
- yield表达式如果用在另一个表达式之中,必须放在圆括号里。
function* fun4() {console.log("你好" + (yield 123));console.log("你好" + (yield 234));}const obj4 = fun4()console.log(obj4.next()); //{value: 123, done: false}console.log(obj4.next()); //{value: 234, done: false}
6.与Iterator接口的关系
说明:由于Generator函数就是遍历器生成函数,因此可以把Geneartor赋值给等下给对象的Symbol.iterator属性,从而使得该对象具有Iterator接口。
const myIter = {}myIter[Symbol.iterator] = function* fun5() {yield 1yield 2return 3}console.log(...myIter);//1 2
说明:没有3这个结果,说明只会遍历yield声明的表达式。(是因为返回对象的done属性为true,for...of循环就会中止)
7.Generator函数时遍历器函数
const fun6 = function* () {}const newFun6 = fun6()console.log(newFun6 === newFun6[Symbol.iterator]()); //true
8. next方法的参数
说明:next方法可以带一个参数,该参数就会当成一个yield表达式的返回值。
function* fun7(x) {let a = 4 * (yield (x + 1))let b = yield (a / 3)return (a + b + x)}const obj5 = fun7(1)console.log(obj5.next()); //{value: 2, done: false}console.log(obj5.next()); //{value: NaN, done: false}console.log(obj5.next()); //{value: NaN, done: true}// 第二次运行next()方法的时候不带参数,导致4*undefined等于NaNconst obj6 = fun7(2)console.log(obj6.next()); //{value: 3, done: false}console.log(obj6.next(2)); //{value: 2.6666666666666665, done: false}console.log(obj6.next(3)); //{value: 13, done: true}
说明:next方法的参数表示上一个yield表达式的返回值,所以在第一次使用next方法,是不需要参数的。v8引擎直接忽略第一个使用的next()方法,只有第二次使用next()方法开始,参数还是有效的。
9.for ...of 循环
说明:for...of循环可以自动遍历Genrator函数运行时生成的Iterator对象,且此时不再需要调用next()方法。
function* fun8() {yield 1yield 2yield 3return 4}for (let i of fun8()) {console.log(i);//1//2//3}
注意:不遍历return是因为返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象。
10.Generator.prototype.throw
说明:Generator函数返回的遍历器对象,可以有throw方法,可以在函数Generartor函数体内捕获。
const fun9 = function* () {try {yield} catch (error) {console.log("内部捕获", error);}}const obj8 = fun9()obj8.next()try {obj8.throw("错误1")obj8.throw("错误2")} catch (error) {console.log("外部捕获", error);}//内部捕获 错误1//外部捕获 错误2
说明:由于Generator函数内部的catch语句已经执行过了,就不会捕获到这个错误了,然后抛出了Generator函数体。
11.Genrator.prototype.return
说明:Generator 函数返回的遍历器函数,还有一个return方法,可以返回指定值,并终结Generator函数。
function* fun10() {yield 1yield 2}const obj10 = fun10()console.log(obj10.next()); //{value: 1, done: false}console.log(obj10.return(10));//{value: 10, done: true}console.log(obj10.next()); //{value: undefined, done: true}
12.try...finally
说明:使用try...finally代码块,且正在执行try代码块那么return()方法会导致立刻进入finally代码块,执行完,整个函数才会结束。
function* fun11() {try {yield 1yield 2} finally {yield 10yield 20}}const obj11 = fun11()console.log(obj11.next()); //1console.log(obj11.return(10)); //{value: 10, done: false}console.log(obj11.next()); //{value: 20, done: false}
13. next(),throw(),return()共同点
说明:其实作用时Generator函数恢复执行,并且使用不同语句替换yield表达式。
14.yield*表达式
说明: 解决Generator函数里面执行另一个Generator函数。
function* fun12() {yield 2yield 3}function* fun13() {yield 4yield* fun12()yield 5}// 等价于function* fun13() {yield 4yield 2yield 3yield 5}
15.对象属性的Generator函数
说明:如果对象的属性时Generator函数,可以简写成下面的形式。
const obj12 = {*fun14() {}}
16.Generator函数的this
说明:因为Generator函数总是返回一个遍历器,它就是Generator函数的实例。要改变可以通过call方法,apply方法等修改this的指向。
function* fun15() {this.a = 666yield 1}const obj14 = {}const obj15 = fun15()obj15.next()console.log(obj15.a); //undefined// 改变thisconst obj16 = fun15.call(obj14)console.log(obj16.next());//{value: 1, done: false}console.log(obj14.a);
注意:构造函数调用以后,这个空对象就是 Generator 函数的实例对象了。
ES6中Generator函数相关推荐
- es6中Generator函数的理解
Generator函数的定义 形式上,Generator函数是一个普通函数,但是有两个特征. 一是,function关键字与函数名之间有一个星号: 二是,函数体内部使用yield表达式,定义不同的内部 ...
- 【ES6】Generator函数详解
[ES6]Generator函数详解 一.Generator函数简介 基本概念 函数写法 yield关键字介绍 二.next方法的参数 三.for...of循环 四.关于普通throw()与Gener ...
- ES6中箭头函数解释
箭头函数 任何可以书写匿名函数的位置,都可以书写箭头函数 箭头函数将会绑定this为函数书写位置的this值 模块化(nodejs带来的模块化) 没有模块化的世界:全局变量污染,难以管理 常见的模块化 ...
- ES6中setTimeout函数的this
ES6中setTimeout函数的this 在编程的过程中有同学遇到不太清楚ES6中this指向的问题,代码抽象如下: function myFunction(){var mthis = this;s ...
- js中Generator函数详解
文章目录 1. Generator的定义和执行 2. Generator中yield在赋值号左边的情况 3. Generator函数嵌套使用 4. 使用generator函数完成网络请求 1. Gen ...
- JS中Generator函数的详解
概念 Generator 函数是 ES6 提供的一种异步编程解决方案.它既是一个生成器,也是一个状态机,内部拥有值及相关的状态,生成器返回一个迭代器 Iterator 对象,我们可以通过这个迭 ...
- ES6中Generator理解
2019独角兽企业重金招聘Python工程师标准>>> 1. 生成器函数声明 function* name(args){}; 2. yield使用 function* hello( ...
- es6中async函数和await表达式的结合使用、async和await的区别
async函数 async和await两种语法结合使用可以让异步代码像同步代码一样 async函数的返回值为promise对象 promise对象的结果由async函数执行的返回值决定 async f ...
- 三,ES6中需要注意的特性(重要)
-----书接上文,前文中我们总结了关于JS的组成部分以及如何快速开展学习JS,相信已经有很多朋友掌握到这些方法.接下来就从更深的ECMAScript开始说起. 1.什么是ES6? ECMAScrip ...
最新文章
- [Ms SQL] 基本創建、修改與刪除
- linux java maven项目_Java maven项目在window下运行正常,部署到Linux环境中启动报错,是由什么引起的?...
- swiper 在turn.js不能滚动
- 全国python一级考试时间_2019年北京全国计算机一级考试时间
- LeetCode MySQL 1321. 餐馆营业额变化增长(over窗口函数)
- iPhone 12系列全新渲染图曝光:4个“杯型” 起售价可能不到5k
- 线程池很难么?带你从头到尾捋一遍,不信你听不懂!
- python之scipy
- python几种设计模式_Python七大原则,24种设计模式
- linux下查看mysql配置文件位置
- android 4.4 root精灵,ROOT精灵: 支持安卓4.3/4.4机型一键ROOT
- FRP搭建内网穿透(亲测有效)
- 安硕科技Java面试过程—(皇德耀世)
- Java 7从入门到精通 前 言
- 【语音之家】AI产业沙龙—火山语音在AI视频译制方向的技术探索与实践
- 计算机硬件发展慢,老电脑卡慢应该更换哪些硬件?看完秒懂
- [WinError 10060]错误
- OAuth2学习(一)——初识OAuth2
- 前端权限管理方案之精确到按钮级别
- NC6.5与UAP开发学习完整教程