generator 和 yield

yield 的使用

 

generator 生成器javascript

yield 能夠使生成器返回屢次 
我習慣於從表象推測,不喜歡官方文檔,寫的字都認識,結果變成句子以後,就一句都看不懂java

因此先舉一個例子來看一下這個東西怎麼玩兒

如今要生成自增的id函數

傳統寫法spa

var public_id = 0;
    function idUp () {
      public_id++;
    }
    idUp() // 須要新id時,調用 idUp ,使外部的變量+1 ,無論是使用變量,仍是把id當作參數傳入函數,函數內部沒法保存id的當前狀態(意思就是,若是沒有外部變量也沒有傳參,函數就不知道id如今是多少).

使用生成器code

function* idUp () {
      let id = 0;
      while (true) {
        yield id
        id++;
      }
    }

    var addId = idUp();
    var newId = addId.next().value; // 須要新id時,使用 addId.next().value, 咱們無需關心外部是否有id,由於id的狀態在函數裏面

注意兩種方式的不一樣之處。對象

 

傳統寫法須要一個全局變量來保存id的狀態,而使用 生成器 狀態保存在生成器中(就這樣理解吧,使用生成器的時候,就不須要定義全局變量了存儲id了)。blog

你們也許會有疑問,使用 while(true) 都死循環了,這個 生成器真的能用麼? 實則yield 會使 生成器暫停,一直到調用next()纔會繼續執行函數,直到遇到下一個yield或者returnip

寫個簡單的 生成器的例子來看一下文檔

function *example () {
      let a = 0;
      console.log('第一次輸出時a的值', a);
      yield a;
      a++;
      console.log('第二次輸出時a的值', a);
      yield a;
      a++;
      console.log('第三次輸出時a的值', a);
      return a;
    }

    var doExample = example(); 
    // 此時並不會輸出 , 我的理解是, 生成器在當作函數執行的時候,實際上是返回了一個 生成器對象,或者說盒子比較恰當,生成器裏面的真正須要執行的代碼被放到了這個盒子裏面。
    console.log(doExample); 
    // 輸出 example {<suspended>}
    console.log(doExample.next()); 
    // 輸出 「第一次輸出時a的值 0 」  和 {value: 0, done: false}
    console.log(doExample.next()); 
    // 輸出 「第二次輸出時a的值 1 」  和 {value: 1, done: false}
    console.log(doExample.next()); 
    // 輸出 「第三次輸出時a的值 2 」  和 {value: 2, done: true}
    console.log(doExample.next()); 
    // 輸出  {value: undefined, done: true}

以上代碼主要就是看一下 生成器的執行流程,主要是 經過這段代碼來理解這樣兩個概念generator

 

1.yield 能夠暫停生成器

2.next 繼續執行生成器直到 遇到下一個yield或者return

如今能夠理解上面使用whil(true)了,可是並不會致使死循環,由於程序的執行實際上是控制在 生成器的next手裏。

另一個須要 特別說一下的知識點是 每次執行next返回的對象裏面 的 done 表明了生成器是否執行完成。能夠理解爲後面是否還有yield 若是還有yield,則 done:false 若是沒有yield了,則爲 true

而且,當生成器執行到末尾的時候,既 done:true 的時候,再次執行 next ,並無任何輸出,且 value 變成了 undefined。這裏爲啥是 undefined 。再寫一個例子。

function *test () {
      let a = 0;
      yield;
      a++;
      yield a;
      a++;
      return a;
    }
    var doTest = test();
    console.log(doTest.next());
    // 輸出 {value: undefined, done: false}
    console.log(doTest.next());
    // 輸出 {value: 1, done: false}
    console.log(doTest.next());
    // 輸出 {value: 2, done: true}
  
console.log(doTest.next());
  // 輸出 {value: undefined, done: true}
 

比較和上一個例子的區別,第一次輸出的 value 的值是 undefined ,由於代碼中 yield 後面什麼都沒有。第二次value的值是1,由於代碼中yield後面接了 a。 意思就是value裏面的值是 yield 後面的東西。

因此,最後輸出 undefined 是否是就理解了 (由於代碼都跑完了,已經沒有yield了,天然就不會再有值了,value天然就是空)

好了就說這麼多了,還有更多坑,你們有興趣的能夠本身去踩踩。

。。。。

相關文章
相關標籤/搜索