ES6 Generator简单使用与抽象理解

ES6 Generator简单使用与抽象理解

1.什么是Generator,及其简单用法。

先看代码:
注:此处并非最简结构,只是一个总结,如果你对Generator没有初步了解,建议先看恰恰虎的Generator 详解

function* fun() {
    yield "a";
    yield "b";
}
function* forFun() {
    yield "A";
    yield "B";
    yield "C";
}

function* gen(x, y) {
    yield 1;
    yield 2;
    yield* fun();
    let z = yield x+y;
    yield z;
    let m = yield x+y;
    yield m;
    for(let item of forFun()){//函数的句柄对象可以通过for of遍历,相当于执行next()直到done为true
        console.log(item);//item为yield后的表达式返回值
    }
    yield "GG"
    return "end"//return的值也会在next后返回到字面量对象的value中,并且done为true。
}
var g = gen(2,3);//并不会执行gen函数,而是生成一个指向gen函数的句柄对象
console.log(g.next());//{value: 1, done: false}
console.log(g.next());//{value:2, done: false}
console.log(g.next());//{value:'a', done: false}
console.log(g.next());//{value:'b', done: false}
console.log(g.next());//{value:5, done: false}
console.log(g.next());//{value:undefined, done: false}
console.log(g.next());//{value:5, done: false}
console.log(g.next(999));//{value:999, done: false}
console.log(g.next());
                      //A
                      //B   
                      //C               
                      //{value:"GG", done: false}
console.log(g.next());//{value: "end", done: true}
console.log(g.next());//{value: undefined, done: true}
  1. 声明Generator函数的方式:在函数名前加*即可。
  2. 执行gen函数:只会生成一个指向gen函数的句柄对象,并不会执行gen函数。
  3. 执行g.next():开始执行gen函数的某一步,每一次next()都只执行到下一个yield就暂停,并且把yield后面的表达式结果返回到字面量对象的value中。
  4. yield:为函数的各个步骤间的“隔断”,每次执行next都是执行完下一个yield后面就暂停并将yield后面表达式返回的结果塞到字面量对象的value中,该字面量对象则是执行next后的返回对象。注(并不是执行完yield的整行,比如上面代码的let z = yield x+y;,只执行x+y并且将x+y的值返回就暂停,并不会对z进行赋值,要在下一次next才会执行let z = yield ***,***是什么请看5)
  5. g.next(999):next时传参,999会变成上一次yeild的值,也就是let z = yield x+y,变成了let z = 999,然后yield z,就会返回{value:999, done: false},如果不传参,就相当于相当于let z = undefined,然后yield z,就会返回{value:undefined, done: false}
  6. yield* fun() :等同于将gen函数改造成如下
function* gen(x, y) {
    yield 1;
    yield 2;
    yield "a";//就相当于将fun里面的yield直接插进来
    yield "b";
    let z = yield x+y;
    yield z;
    let m = yield x+y;
    yield m;
    for(let item of forFun()){
        console.log(item);
    }
    yield "GG"
    return "end"
}

7.for of循环:使用for of循环可以循环指向Generator函数的句柄对象,相当于直接执行它的所有步骤直到返回对象的donetrue,并且它循环的item为每个yield后表达式的返回值。并且你也可以在循环内部写入yield来将for循环分割成一段一段执行。
8.Generator函数内部的returnreturn为非必须,如果存在的话则在最后donetrue时,value的值即是return后面表达式的值。
9.Generator函数的句柄对象的return()方法:

function* gen(x,y){
   	  yield 1;
   	  yield 2;
   	  yield 3;
   }
   var g = gen();
   g.next();//{value: 1, done: false}
   g.next();//{value: 2, done: false}
   g.return(5);//{value: 5, done: true}
   g.next();//{value: undefined, done: true}

return()方法作用如上,即可以截断yield,并且传入的参数即使返回的对象value值,done会被置为true

Generator的抽象理解(流水线)

  1. Generator函数就像一个流水线的图纸,
  2. 当执行该函数时就相当于创建了一条流水线,但是并未开启,如果在执行函数时传入了参数,就相当于流水线的原材料,
  3. 在执行next()时就相当于开启了流水席线,
  4. 当产品撞到了yield(即代码走到了yield)流水线就会被暂停,
  5. 暂停后会把这一阶段的半成品交给操作员,操作员决定是否对该半成品进行其他操作,或者加入新的原材料,或者不进行操作,如果需要进行操作就将字面量对象的value进行计算在下一次next()时当作参数传入,如果需要加入新的原材料就将新的值在下一次next()时当作参数传入,如果不需要任何操作即把最近一次的next()的返回对象的value当作参数执行下一次next
  6. 当一次步骤结束(next结束)我们发现需要插入其他工序,即使用yield*自定义Generator函数()
  7. 当我们发现只需要无脑开动流水线直到结束,我们就可以使用for of循环
  8. 当我们发现需要提前终止流水席生产,那就执行return().

Generator的作用

Generator的最大特点就是一个可以暂停并且重启的函数,并且在暂停重启间可以注入新的参数,这样就给开发流程带来了更多的灵活性,可以使代码像一个流水线一样,随时暂停开启并且注入新的参数。虽然常规开发你在自己调用一系列的函数过程中也可以使用各种if判断来决定函数的执行与不执行,也能达到控制代码流程的作用,但是Generator给了我们更加美观,规范化,便捷的开发方式,网上很多人说Generator用来解决回调地狱,其实回调地狱直接使用Promise或者async await更加方便实用,使用 Generator反倒会不易读。(以上均为个人浅薄观点,如有错误请评论区指出)。

本文参考资料:

ES6系列教程第三篇–Generator 详解
es6 generator到底有什么用?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值