摘要:語法上,首先可以把它理解成,函數是一個狀態機,封裝了多個內部狀態。返回的遍歷器對象,可以依次遍歷函數內部的每一個狀態。
寫在前面:
這一篇是關于ES6中生成器函數相關總結和理解...
Generator函數的定義在阮一峰老師的書中的說法是:
Generator 函數有多種理解角度。語法上,首先可以把它理解成,Generator 函數是一個狀態機,封裝了多個內部狀態。執行 Generator 函數會返回一個遍歷器對象,也就是說,Generator 函數除了狀態機,還是一個遍歷器對象生成函數。返回的遍歷器對象,可以依次遍歷 Generator 函數內部的每一個狀態。
我的理解:
生成器函數可以理解為: 函數內部是由多個小函數組成的, 使用yield關鍵字將函數內部 分割成多個塊區域; 并且當函數執行時, 遇到yield就會停止, 并且將yield 后面的表達式結果輸出(當然外部要調用next()方法); 下次再調用next()方法時, 就從上一個停止的地方開始執行(這意味著函數有有記憶功能); 如果下面沒有再遇到yield的話 就像普通函數執行完. 函數的返回值是一個可迭代對象(遍歷器對象); 我喜歡叫可迭代對象, 或者說可遍歷對象...
function CreateIterator(iterator) { // 定義一個初始下標用來判斷 let nextIndex = 0; // 返回對象: 包含的next方法, return { next: function () { // 返回一個對象: value是當前對象下標對應的值, done是是否遍歷完成 return nextIndex < iterator.length ? // i++ 先參數運算在 自增1 {value: iterator[nextIndex++], done: false} : {value: undefined, done: true}; } } } // 實例化一個遍歷器 let iter1 = CreateIterator([1,2,3,4,5]); console.log(iter1); // 一個具有next方法的對象 console.log(iter1.next().value); // 1 console.log(iter1.next().value); // 2 console.log(iter1.next().value); // 3 console.log(iter1.next().value); // 4 console.log(iter1.next().value); // 5 console.log(iter1.next().value); // undefined生成器函數的使用
generator生成器函數的使用: function *fn() { 代碼1; yield; 代碼2; } 普通函數: 執行到底 生成器函數: 遇到yield會暫停,交出執行權,下次執行從上次的停止的位置繼續 生成器函數返回值為: 生成器對象 生成器對象.next()方法才能執行 函數體中的代碼 // 可以解決函數回調嵌套的問題; 解決耗時操作 function *func() { // 請求數據. // yield ajax() // 處理數據 } // generator函數本質上 分割成多個小函數來執行... yield關鍵字前后 // 遇到yield就暫停; 沒有就往下執行... // yield 起到了 暫停函數執行的作用關于yield關鍵字的理解 yield傳值 yield輸出值
舉個栗子:
function *g2(x, y) { let sum = x+y; yield sum; // sum是第一個輸出結果 let agv = sum / 2; yield agv; // agv 是第二個輸出的結果 return {"和": sum, "平均數": agv}; // 最后一個結果 } let gg2 = g2(100, 20); console.log(gg2.next().value); // 120 console.log(gg2.next().value); // 60 console.log(gg2.next().value); // { "和": 120, "平均數": 60 }Generator的應用
這里只做一個簡單舉例, 像我們平時使用的ES7中的 async 函數; 他就是生成器函數的一種應用; 它其實是 Generator 函數的語法糖。
借用ES6入門中的一個例子: 兩種方式去讀取文件
const fs = require("fs"); const readFile = function (fileName) { return new Promise(function (resolve, reject) { fs.readFile(fileName, function(error, data) { if (error) return reject(error); resolve(data); }); }); }; // 1.使用生成器函數 讀取文件 const gen = function* () { const f1 = yield readFile(__dirname + "/first.json"); const f2 = yield readFile(__dirname + "/second.json"); console.log(f1.toString()); // 沒有輸出; 因為 f1 拿到是一個 Iterator 對象 console.log(f2.toString()); }; // 使用 async + await 讀取; 注意兩種需配合使用 const asyncReadFile = async function () { const f1 = await readFile(__dirname + "/first.json"); const f2 = await readFile(__dirname + "/second.json"); console.log(f1.toString()); //async函數的返回值是 Promise 對象 console.log(f2.toString()); }; gen(); // 沒有值, 需要用 next()方法去取值 asyncReadFile() // 返回值 {"hello": "first"} {"hello": "second"}
所以; 我們這里對比一下; async函數是將 Generator 函數的星號(*)替換成async,將yield替換成await,大大方便了我們的使用。
平時的異步代碼 我們就可以使用 async + await的形式來實現...
比如vue中的一個ajax請求去獲取數據
methods: { async getApi() { let res = await axios.get("url") // 這里的執行順序是同步的... console.log(res) } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102680.html
摘要:調用函數后和普通函數不同的是,該函數并不立即執行,也不返回函數執行結果,而是返回一個指向內部狀態的對象,也可以看作是一個遍歷器對象。第一個只是用來啟動函數內部的遍歷器,傳參也沒有多大意義。 之前斷斷續續接觸到了一些ES6的知識,異步編程方面聽得比較多的就是Promise,直到最近比較系統地學習了ES6的新特性才發現Generator這個神奇的存在,它可以實現一些前所未有的事情,讓我頓時...
摘要:返回的遍歷器對象可以依次遍歷函數內部的每一個狀態。示例內部捕獲外部捕獲內部捕獲外部捕獲上面代碼遍歷器對象連續拋出兩個錯誤,第一個被函數體內的捕獲。上面代碼中,首先執行函數,獲取遍歷器對象,然后使用方法第二行,執行異步任務的第一階段。 參考 來源《ecmascript6 入門》generator部分 認識generator函數 形式上,generator函數有兩個特點:一是functio...
摘要:函數返回的遍歷器對象,還有一個方法,可以返回給定的值,并且終結遍歷函數。這被稱為表達式個人理解主要用作遍歷具有遍歷器接口的對象或函數。完整形式函數的函數總是返回一個遍歷器,規定這個遍歷器是函數的實例,也繼承了函數的對象上的方法。 語法上 首先可以把它理解成,Generator 函數是一個狀態機,封裝了多個內部狀態。執行 Generator 函數會返回一個遍歷器對象,也就是說,Gener...
摘要:同時,迭代器有一個方法來向函數中暫停處拋出一個錯誤,該錯誤依然可以通過函數內部的模塊進行捕獲處理。 本文翻譯自:Diving Deeper With ES6 Generators 由于個人能力有限,翻譯中難免有紕漏和錯誤,望不吝指正issue ES6 Generators:完整系列 The Basics Of ES6 Generators Diving Deeper With E...
摘要:返回的遍歷器對象,可以依次遍歷函數內部的每一個狀態。方法調用遍歷器對象的方法,使得指針移向下一個狀態。運行結果就是使用一個遍歷器,遍歷了多個函數,有遞歸的效果。 1、Generator簡介 基本概念 Generator函數有多種理解角度。從語法上,首先可以把它理解成,Generator函數是一個狀態機,封裝了多個內部狀態。 執行Generator函數會返回一個遍歷器對象,也就是說,Ge...
摘要:換句話說,我們很好的對代碼的功能關注點進行了分離通過將使用消費值得地方函數中的邏輯和通過異步流程來獲取值迭代器的方法進行了有效的分離。但是現在我們通過來管理代碼的異步流程部分,我們解決了回調函數所帶來的反轉控制等問題。 本文翻譯自 Going Async With ES6 Generators 由于個人能力知識有限,翻譯過程中難免有紕漏和錯誤,還望指正Issue ES6 Gener...
閱讀 1266·2021-11-24 09:39
閱讀 1517·2021-09-07 09:59
閱讀 3479·2019-08-30 15:54
閱讀 2474·2019-08-30 11:00
閱讀 2669·2019-08-29 15:06
閱讀 2160·2019-08-26 13:52
閱讀 427·2019-08-26 13:24
閱讀 2489·2019-08-26 12:20