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

suliver發表於2021-09-09
宣告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小磊_
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2370/viewspace-2813544/,如需轉載,請註明出處,否則將追究法律責任。

相關文章