ES6的Generator函数(2018-06-21)

声明Generator函数

     Generator函数,又称生成器函数,是ES6的一个重要的新特性。

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

     注意:
1、普通函数用function来声明,Generator函数用function*声明。
2、Generator函数内部有新的关键字:yield,普通函数没有。

调用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}

     函数执行后,返回了一个:[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}
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();

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

Generator函数的用途

      它可以控制函数的内部状态,依次遍历每个状态;可以根据需要,轻松地让函数暂停执行或者继续执行。利用Generator函数暂停执行的作用,可以将异步操作的语句写到yield后面,通过执行next方法进行回调。

    原文作者:a小磊_
    原文地址: https://www.jianshu.com/p/876aea4cc12f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞