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