日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Iterator 遍历器的简单使用

發(fā)布時間:2023/12/31 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Iterator 遍历器的简单使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Object接口 實現Iterator

我們可以使用 ES6 的展開運算符 … 和 for…of… 去遍歷帶有 Iterator 接口的數據結構,需要注意的是,Object 本身不具備 Iterator 接口,所以我們無法通過 … 把一個對象擴展到一個數組中,并且會報錯,我們可以通過代碼手動將 Object 類型實現 Iterator 接口。

沒有實現Iterator 接口的Object

let obj = {a: 1,b: 2,c: 3 };let arr = [...obj];

結果:


實現Iterator 接口的Object

// 通過 Generator 函數給 Object 擴展 Iterator 接口 Object.prototype[Symbol.iterator] = function*() {for (var key in this) {yield this[key];} };// 測試 Iterator 接口 let obj = {a: 1,b: 2,c: 3 };let arr = [...obj];console.log(arr); // [1, 2, 3]

結果:


模擬 Generator

Generator 函數是一個生成器,調用后會返回給我們一個 Iterator 遍歷器對象,在對象中有一個 next 方法,調用一次 next,幫我遍歷一次,返回值為一個對象,內部有 value 和 done 兩個屬性,value 屬性代表當前遍歷的值,done 屬性代表是否遍歷完成,如果遍歷完成后繼續(xù)調用 next,返回的對象中 value 屬性值為 undefined,done 屬性值為 true,這個遍歷器在進行數據遍歷時更像給我們提供了一個暫停功能,每次都需要手動調用 next 去進行下一次遍歷。

// 模擬遍歷器生成函數 function iterator(arr) {var i = 0;return {next: function() {var done = i >= arr.length;var value = !done ? arr[i++] : undefined;return {value: value,done: done};}}; }

測試一下模擬的遍歷器生成函數:

// 測試 iterator 函數 var arr = [1, 3, 5];// 遍歷器 var result = iterator(arr);result.next(); // {value: 1, done: false} result.next(); // {value: 3, done: false} result.next(); // {value: 5, done: false} result.next(); // {value: undefined, done: true}

Generator 的基本使用

在普通的函數 function 關鍵字后加一個 * 就代表聲明了一個生成器函數,執(zhí)行后返回一個遍歷器對象,每次調用遍歷器的 next 方法時,遇到 yield 關鍵字暫停執(zhí)行,并將 yield 關鍵字后面的值會作為返回對象中 value 的值,如果函數有返回值,會把返回值作為調用 next 方法進行遍歷完成后返回的對象中 value 的值,果已經遍歷完成,再次 next 調用這個 value 的值會變成 undefined。

// 生成器函數 function* gen() {yield 1;yield 2;return 3; }// 遍歷器 let it = gen();it.next(); // {value: 1, done: false} it.next(); // {value: 2, done: false} it.next(); // {value: 3, done: true} it.next(); // {value: undefined, done: true}

觀察兩個結果:

return

無return

在 Generator 函數中可以使用變量接收 yield 關鍵字執(zhí)行后的返回值,只是接收的值并不是 yield 關鍵字后面表達式執(zhí)行的結果,而是遍歷器在下一次調用 next 方法時傳入的參數。

在 Generator 函數中,如果在其他函數或方法調用的回調內部(函數的執(zhí)行上/下文發(fā)生變化)不能直接使用 yield 關鍵字。

/ 正確的寫法 function* gen(arr) {for(let i = 0; i < arr.length; i++) {yield arr[i];} }

如果在一個 Generator 函數中調用了另一個 Generator 函數,在調用外層函數返回遍歷器的 next 方法時是不會遍歷內部函數返回的遍歷器的。

// 外層的生成器函數 function* genOut() {yield "a";yield genIn();yield "c"; }// 內層的生成器函數 function* genIn() {yield "b"; }// 遍歷器 let it = genOut();it.next(); // {value: 'a', done: false} it.next(); // 返回 genIn 的遍歷器對象 it.next(); // {value: 'c', done: false} it.next(); // {value: undefined, done: true}

在 genOut 返回的遍歷器調用 next 遇到 yield* 表達式時幫我們去遍歷了 genIn 返回的遍歷器,其實 yield* 內部做了處理,等同于下面代碼:

// 外層的生成器 function* genOut() {yield "a";for (let v of genIn()) {yield v;}yield "c"; }// 內層的生成器 function* genIn() {yield "b"; }// 遍歷器 let it = genOut();it.next(); // {value: 'a', done: false} it.next(); // {value: 'b', done: false} it.next(); // {value: 'c', done: false} it.next(); // {value: undefined, done: true}

Generators 與 Promise 結合

因為 Generator 函數在執(zhí)行時遇到 yield 關鍵字會暫停執(zhí)行,那么 yield 后面可以是異步操作的代碼,比如 Promise,需要繼續(xù)執(zhí)行,就手動調用返回遍歷器的 next 方法,因為中間有一個等待的過程,所以在執(zhí)行異步代碼的時候避免了回調函數的嵌套,在寫法上更像同步,更容易理解。

我們來設計一個 Generator 函數與 Promise 異步操作結合的使用場景,假設我們需要使用 NodeJS 的 fs 模塊讀取一個文件 a.txt 的內容,而 a.txt 的內容是另一個需要讀取文件 b.txt 的文件名,讀取 b.txt 最后打印讀取到的內容 “Hello world”。

// 引入依賴 let fs = require("fs"); let util = require("util");// 將 readFile 方法轉換成 Promise let read = util.promisify(fs.readFile);// 生成器函數 function* gen() {let aData = yield read("1.txt", "utf8");let bData = yield read(aData, "utf8");return bData; }// 遍歷器 let it = gen();it.next().value.then(data => {it.next(data).then(data => {console.log(data); // Hello world}); });

co 庫的使用

co 庫是基于 Generator 和 Promise 的,這個庫能幫我們實現自動調用 Generator 函數返回遍歷器的 next 方法,并執(zhí)行 yield 后面 Promise 實例的 then 方法,所以每次 yield 后面的異步操作返回的必須是一個 Promise 實例,代碼看起來像同步,執(zhí)行其實是異步,不用自己手動進行下一次遍歷.

總結

以上是生活随笔為你收集整理的Iterator 遍历器的简单使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。