JS generator(生成器)


筆記整理自:廖雪峰老師的JS教程

簡介

generator(生成器)是ES6標准引入的新的數據類型一個generator看上去像一個函數,但可以返回多次

與函數的不同之處

generator和函數不同的是,generatorfunction*定義(注意多出的*號),並且,除了return語句,還可以用yield返回多次

大多數同學立刻就暈了,generator就是能夠返回多次的“函數”?返回多次有啥用?

還是舉個栗子吧。

我們以一個著名的斐波那契數列為例,它由01開頭:

0 1 1 2 3 5 8 13 21 34 ...

要編寫一個產生斐波那契數列的函數,可以這么寫:

函數寫法
function fib(max) {
    var
        t,
        a = 0,
        b = 1,
        arr = [0, 1];
    while (arr.length < max) {
        [a, b] = [b, a + b];
        arr.push(b);
    }
    return arr;
}

// 測試:
fib(5); // [0, 1, 1, 2, 3]
fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

函數只能返回一次,所以必須返回一個Array。但是,如果換成generator,就可以一次返回一個數,不斷返回多次

generator寫法
function* fib(max) {
    var
        t,
        a = 0,
        b = 1,
        n = 0;
    while (n < max) {
        yield a;
        [a, b] = [b, a + b];
        n ++;
    }
    return;
}

generator寫完后直接調用試一下:fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}

直接調用一個generator和調用函數不一樣,fib(5)僅僅是創建了一個generator對象,還沒有去執行它

generator調用

generator對象的next()方法調用
var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}

next()方法會執行generator的代碼,然后,每次遇到yield x;就返回一個對象{value: x, done: true/false},然后“暫停”。返回的value就是yield的返回值,done表示這個generator是否已經執行結束了。如果donetrue,則value就是return的返回值。
當執行到donetrue時,這個generator對象就已經全部執行完畢,不要再繼續調用next()

for ... of循環調用
for (var x of fib(10)) {
    console.log(x); // 依次輸出0, 1, 1, 2, 3, ...
}

這種方式不需要我們自己判斷done

用處

實現需要用面向對象才能實現的功能
把異步回調代碼變成“同步”代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM