生成器和迭代器
一、Generator生成器函數
Generator函數是ES2015提出的異步的解決方案,與普通的函數有很大的不同;
生成器提供了一種【中斷機制】,使得子程序可以暫時返回,等在之后的某個時刻,繼續回來運行。
特點:
(1)generator函數與普通函數不同,普通函數一旦調用就會執行完,但是generator函數中間可以暫停,執行一會歇一會。
(2)在function關鍵字后面跟一個(*)號;
(3)在函數體內部使用yield表達式作為一個狀態,實現暫停;
(4)generator函數執行并不會有什么效果,而是返回一個迭代器對象,之后調用迭代器的next方法會返回一個值對象。
舉例說明:
?
function *go(a){console.log(1);//yield語句只是標識符,并沒有返回值//yield左邊等于next()傳來的參數值,沒傳參則為undefined,yield右邊是next()的返回值let b=yield a;console.log(2);let c=yield b;console.log(3);return c;}let iterator=go('aaa');let r1=iterator.next();//第一次next()不用傳參console.log(r1);// 1 {value: "aaa", done: false} let r2=iterator.next('bbb');console.log(r2);//2 {value: "bbb", done: false} let r3=iterator.next();console.log(r3);//3 {value: undefined, done: true} done屬性值代表當前迭代是否完成。//例2 function *gen(x){var y=2*(yield (x+1));var z=yield (y/3);return x+y+z; } var t=gen(5); console.log(t.next());//{value: 6, done: false} console.log(t.next(12));//{value: 8, done: false} console.log(t.next(13));//{value: 42, done: true} //解析:yield (x+1)表達式將傳遞值6到外部,在第二次調用next(12)的時候,傳遞12到generator函數內部作為yield(x+1)表達式的值,因此y被賦值12*12=24.接下來,下一條yield(y/3) 將向外傳值值8.第三次調用next(13)傳遞13到generator函數內部給yield(y/3),所以z的值為13?
?
在生成器中的return值:便利返回對象的done值為true時迭代即結束,不會對該value處理。
function *createIterator() {yield 1;return 42;yield 2; } let iterator1 = createIterator(); console.log(...iterator); // 1?
async是Generator函數的語法糖。async的實現原理就是將Generator函數和自動執行器包裝在一個函數里。
?相比于generator,Async函數有以下幾點改進:
(1)內置執行器。generator函數的執行必須依賴執行器,而async函數自帶執行器,調用的方式和普通函數的調用一樣。
(2)返回值是promise對象。比起generator函數返回的iterator對象更加方便,可以直接使用then()方法調用。
?
二、Iterator迭代器
迭代器是一種特殊的對象,它具有一些專門為迭代過程設計的接口,所有的迭代器對象都有一個next()方法,每次調用都返回一個結果對象。該結果對象有兩個屬性:value(表示下一個將要返回的值)和done(布爾值,表示迭代過程是否結束)
?
手動實現一個簡單的迭代器
測試數據:
?
?
三、可迭代對象
1、可迭代對象具有Symbol.iterator屬性,是一種與迭代器密切相關的對象。
在ES6中所有集合對象(Array、Set結構和Map結構)和String都是可迭代對象,這些對象都有默認的迭代器。
ES6中新加入的特性for of循環需要用到可迭代對象這些功能。
for-of循環每執行一次都會調用可迭代對象的next()方法,并將迭代器返回的結果對象的value屬性存儲在一個變量中,循環將持續執行這一過程直到返回對象的done屬性值為true。
通過生成器創建的迭代器也是可迭代對象,因為生成器默認會為Symbol.iterator屬性賦值。
?
2、判斷一個數據是否具有可迭代能力,只有當數據具有Symbol.iterator屬性的時候才可以使用for-of進行迭代。
? ? ? ??
?
3、默認迭代器
ES6為很多內置對象提供了默認的迭代器,只有當內建的迭代器不能滿足需求時才自己創建迭代器。
S6的三個集合對象:Set、Map、Array都有默認的迭代器,常用的如values()方法、entries()方法、keys()方法都返回一個迭代器。其值區別如下:
- entries():多個鍵值對
- values():集合的值
- keys():集合的鍵
?
我們可以通過Symbol.iterator屬性來訪問可迭代對象的默認迭代器。例如對一個數組:
?
?
思考:
1、既然數組等具有可迭代能力,但是為什么我們直接用arr.next()或報錯?
是因為可迭代對象不代表是一個迭代器,只有迭代器才具有next()方法。所以具有可迭代能力的對象,如果想要使用next()方法,必須先轉換為迭代器。
可迭代對象不一定是迭代器,但是迭代器一定是可迭代對象。
?
?
?
co模塊?
用于generator函數的自動執行。是我們可以不用編寫generator函數的執行器。
co模塊其實是將兩種自動執行器(thunk函數和promise對象)包裝成一個模塊,然后返回的是promise對象。
轉載于:https://www.cnblogs.com/xiaoan0705/p/11404861.html
總結
- 上一篇: 预处理器Less和Sass
- 下一篇: webpack 零基础到工程实战(1)