ES6 generator 基礎


參考文檔

Generator是ES6的新特性,通過yield關鍵字,可以讓函數的執行流掛起,那么便為改變執行流程提供了可能。

創建Generator

function * main() {
    var x = yield 1;
    var y = yield 2;
    var z = yield 3;
}

使用以上語法就可以聲明一個generator,注意main是一個函數

判斷是否為generator

function isGen(fn) {
    return 'function' === typeof fn && fn.constructor.name === 'GeneratorFunction';
}

generator的構造器

main.constructor //function GeneratorFunction() { [native code] }

Generator Object

生成Generator Object

var g= main();
console.info(typeof g)

g是Generator Object,在MDN上稱為generator-iterator

Generator Object方法

next

雖然main被調用了,但是並沒有執行里面的方法體,而是返回了一個Generator Object,如何調用里面的方法體呢,這就要使用next方法

console.log(g.next());//{value: 1, done: false}

next方法在es6中定義如下

The next function’s behavior is:

1.If this is not a generator object, Throw Error

2.Call this.[[Send]] with single argument undefined

3.Return the result

next方法會執行函數體,直到遇到第一個yield語句,然后掛起函數執行,等待后續調用。但是next會返回一個對象,這個對象有2個key,value表示yield語句后面的表達式的值('hello'),done是個布爾值,表示函數體是否已經執行結束。再次調用g。next時,執行流在掛起的地方繼續執行,直到遇到第2個yield,依次類推。

console.log(g.next());//{value: 2, done: false}
console.log(g.next());//{value: 3, done: false}
console.log(g.next());//{value: undefined, done: true}

Tips:有時候我們把yield看成是return

next方法也接受傳參,傳入參數作為yield語句的返回值;

function *main() {
    var x = yield 1;
    console.log(x)
}

var g=main();
g.next();
g.next("hello world") //hello world

next方法的特性很總要,很多基於generator做的流程控制都基於這個特性。

異常處理

function * main(){
    yield;a+b
}

var m=main()

m.next()
m.next()    //Uncaught ReferenceError: a is not defined

我們可以使用catch捕獲異常

yield 和 yield*

yield* 是委托提取器。yield 是你給什么它提取什么,但是 yield* 會繼續向下請求,直到沒的提取為止。

function* a() { yield 1; yield 2; yield 3; }
function* b() { yield 4; yield* a(); yield 5; }
function* c() { yield 6; yield* b(); yield 7; }

var cc = c();

cc.next(); // {value: 6, done: false}
cc.next(); // {value: 4, done: false}
cc.next(); // {value: 1, done: false}
cc.next(); // {value: 2, done: false}
cc.next(); // {value: 3, done: false}
cc.next(); // {value: 5, done: false}
cc.next(); // {value: 7, done: false}
cc.next(); // {value: undefined, done: true}

DEMO

function * G () {
    console.log(yield function () {
        console.log("func");
    });
}

var g = G();

console.log(g.next());
//{ value: [Function], done: false }
console.log(g.next("hi"));
//hi
//{ value: undefined, done: true }

支持情況

  • Chrome 35+ (about://flags中開啟)
  • Firefox 31+ (默認開啟)
  • nodejs harmony


免責聲明!

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



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