摘要:函數(shù)從暫停狀態(tài)到恢復(fù)運(yùn)行,它的上下文狀態(tài)是不變的。也就是說,可以在函數(shù)運(yùn)行的不同階段,從外部向內(nèi)部注入不同的值,從而調(diào)整函數(shù)行為。循環(huán)循環(huán)可以自動(dòng)遍歷函數(shù)時(shí)生成的對(duì)象,且此時(shí)不再需要調(diào)用方法。
基本概念
狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài);
返回一個(gè)遍歷器對(duì)象,通過改對(duì)象可以一次遍歷Generator函數(shù)內(nèi)部的每一個(gè)狀態(tài)
帶*號(hào),yeild表達(dá)式定義不同的內(nèi)部狀態(tài);
調(diào)用 Generator 函數(shù)后,該函數(shù)并不執(zhí)行,返回的也不是函數(shù)運(yùn)行結(jié)果,而是一個(gè)指向內(nèi)部狀態(tài)的指針對(duì)象,也就是遍歷器對(duì)象;
Generator 函數(shù)是分段執(zhí)行的,yield表達(dá)式是暫停執(zhí)行的標(biāo)記,而next方法可以恢復(fù)執(zhí)行;
暫停標(biāo)志
next()方法允許邏輯
遇到y(tǒng)ield表達(dá)式,就暫停執(zhí)行后面的操作,并將緊跟在yield后面的那個(gè)表達(dá)式的值,作為返回的對(duì)象的value屬性值;
下一次調(diào)用next方法時(shí),再繼續(xù)往下執(zhí)行,直到遇到下一個(gè)yield表達(dá)式;
沒有再遇到新的yield表達(dá)式,就一直運(yùn)行到函數(shù)結(jié)束,直到return語句為止,并將return語句后面的表達(dá)式的值,作為返回的對(duì)象的value屬性值;
如果該函數(shù)沒有return語句,則返回的對(duì)象的value屬性值為undefined;
yield表達(dá)式只能用在 Generator 函數(shù)里面,用在其他地方都會(huì)報(bào)錯(cuò)。
var arr = [1, [[2, 3], 4], [5, 6]]; var flat = function* (a) { a.forEach(function (item) { if (typeof item !== "number") { yield* flat(item); } else { yield item; //forEach()的參數(shù)是一個(gè)普通函數(shù)使用yield會(huì)報(bào)錯(cuò),可以使用for循環(huán)解決這個(gè)問題 } }); }; for (var f of flat(arr)){ console.log(f); }
使用for循環(huán)改正
var arr = [1, [[2, 3], 4], [5, 6]]; var flat = function* (a) { var length = a.length; for (var i = 0; i < length; i++) { var item = a[i]; if (typeof item !== "number") { yield* flat(item); } else { yield item; } } }; for (var f of flat(arr)) { console.log(f); }// 1, 2, 3, 4, 5, 6
yield表達(dá)式如果用在另一個(gè)表達(dá)式之中,必須放在圓括號(hào)里面;
yield表達(dá)式用作函數(shù)參數(shù)或放在賦值表達(dá)式的右邊,可以不加括號(hào)
與Iterator的關(guān)系可以把 Generator 賦值給對(duì)象的Symbol.iterator屬性,從而使得該對(duì)象具有 Iterator 接口
var myIterable = {}; myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; }; [...myIterable] // [1, 2, 3]next()方法的參數(shù)
yield表達(dá)式本身沒有返回值,或者說總是返回undefined。next方法可以帶一個(gè)參數(shù),該參數(shù)就會(huì)被當(dāng)作上一個(gè)yield表達(dá)式的返回值。
function* f() { for(var i = 0; true; i++) { var reset = yield i; if(reset) { i = -1; } } } var g = f(); g.next() // { value: 0, done: false } g.next() // { value: 1, done: false } g.next(true) // { value: 0, done: false }
Generator 函數(shù)從暫停狀態(tài)到恢復(fù)運(yùn)行,它的上下文狀態(tài)(context)是不變的。通過next方法的參數(shù),就有辦法在 Generator 函數(shù)開始運(yùn)行之后,繼續(xù)向函數(shù)體內(nèi)部注入值。也就是說,可以在 Generator 函數(shù)運(yùn)行的不同階段,從外部向內(nèi)部注入不同的值,從而調(diào)整函數(shù)行為。
分析以下代碼允許的結(jié)果:
function* foo(x) { var y = 2 * (yield (x + 1)); var z = yield (y / 3); return (x + y + z); } var a = foo(5); a.next() // Object{value:6, done:false} a.next() // Object{value:NaN, done:false} a.next() // Object{value:NaN, done:true} var b = foo(5); b.next() // { value:6, done:false } b.next(12) // { value:8, done:false } b.next(13) // { value:42, done:true }
next()傳參,參數(shù)代表上一次yeild表達(dá)式返回的值,因此第一次使用next()傳參是無效的;
function* dataConsumer() { console.log("Started"); console.log(`1. ${yield}`); console.log(`2. ${yield}`); return "result"; } let genObj = dataConsumer(); genObj.next(); // Started genObj.next("a") // 1. a genObj.next("b") // 2. b
如果想第一次調(diào)用next()方法就能夠輸入值,可以在Genrator函數(shù)外再包一層
function wrapper(generatorFunction) { return function (...args) { let generatorObject = generatorFunction(...args); generatorObject.next(); return generatorObject; }; } const wrapped = wrapper(function* () { console.log(`First input: ${yield}`); return "DONE"; }); wrapped().next("hello!")// First input: hello!
上述代碼在wrapper函數(shù)中,首先調(diào)用一次next方法,再返回遍歷器對(duì)象。當(dāng)用戶自己調(diào)用next方法時(shí),看起來就像是第一次調(diào)用,但實(shí)際上,這是第二次調(diào)用next方法。
for...of循環(huán)for...of循環(huán)可以自動(dòng)遍歷 Generator 函數(shù)時(shí)生成的Iterator對(duì)象,且此時(shí)不再需要調(diào)用next方法。
function* foo() { yield 1; yield 2; yield 3; yield 4; yield 5; return 6; } for (let v of foo()) { console.log(v); } // 1 2 3 4 5
這里需要注意,一旦next方法的返回對(duì)象的done屬性為true,for...of循環(huán)就會(huì)中止;
Generator給對(duì)象添加Iterator方法一
function* objectEntries(obj) { let propKeys = Reflect.ownKeys(obj); for (let propKey of propKeys) { yield [propKey, obj[propKey]]; } } let jane = { first: "Jane", last: "Doe" }; for (let [key, value] of objectEntries(jane)) { console.log(`${key}: ${value}`); } // first: Jane // last: Doe
方法二將 Generator 函數(shù)加到對(duì)象的Symbol.iterator屬性上面。
function* objectEntries() { let propKeys = Object.keys(this); for (let propKey of propKeys) { yield [propKey, this[propKey]]; } } let jane = { first: "Jane", last: "Doe" }; jane[Symbol.iterator] = objectEntries; for (let [key, value] of jane) { console.log(`${key}: ${value}`); } // first: Jane // last: Doe
【完】
作者簡(jiǎn)介:鄭佳歡,蘆葦科技web前端實(shí)習(xí)生,公司作品:口紅挑戰(zhàn)網(wǎng)紅小游戲、服務(wù)端渲染官網(wǎng)。擅長(zhǎng)網(wǎng)站建設(shè)、公眾號(hào)開發(fā)、微信小程序開發(fā)、小游戲、公眾號(hào)開發(fā),專注于前端領(lǐng)域框架、交互設(shè)計(jì)、圖像繪制、數(shù)據(jù)分析等研究。 訪問 www.talkmoney.cn 了解更多
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104506.html
摘要:返回的遍歷器對(duì)象,可以依次遍歷函數(shù)內(nèi)部的每一個(gè)狀態(tài)。由于函數(shù)就是遍歷器生成函數(shù),因此可以把賦值給對(duì)象的屬性,從而使得該對(duì)象具有接口。函數(shù)從暫停狀態(tài)恢復(fù)運(yùn)行,它的上下文狀態(tài)時(shí)不變的。從語義上講,第一個(gè)方法用來啟動(dòng)遍歷器對(duì)象,所以不用帶有參數(shù)。 基本概念 Generator函數(shù)是ES6提供的一種異步編程解決方案,語法行為與傳統(tǒng)函數(shù)完全不同。Generator函數(shù)有多種理解角度。語法上,首先...
摘要:以下展示它是如何工作的函數(shù)使用構(gòu)造函數(shù)創(chuàng)建一個(gè)新的對(duì)象,并立即將其返回給調(diào)用者。在傳遞給構(gòu)造函數(shù)的函數(shù)中,我們確保傳遞給,這是一個(gè)特殊的回調(diào)函數(shù)。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關(guān)注我的專欄,之后的博文將在專欄同步: Encounter的掘金專欄 知乎專欄...
摘要:如果你已經(jīng)理解基礎(chǔ)可以直接跳過這部分和語法部分,直接看深入理解的部分。的參數(shù)可以傳入一個(gè)參數(shù),來作為上一次的表達(dá)式的返回值,就像我們上面說的會(huì)讓等于。 這篇文章旨在幫你真正了解Generator,文章較長(zhǎng),不過如果能花時(shí)間耐心看完,相信你已經(jīng)能夠完全理解generator 為什么要用generator 在前端開發(fā)過程中我們經(jīng)常需要先請(qǐng)求后端的數(shù)據(jù),再用拿來的數(shù)據(jù)進(jìn)行使用網(wǎng)頁頁面渲染等操...
摘要:最后,調(diào)用這個(gè)函數(shù),得到一個(gè)遍歷器對(duì)象并賦值給變量。值得注意的是如果函數(shù)內(nèi)部沒有部署代碼塊,那么遍歷器對(duì)象的方法拋出的錯(cuò)誤,將被外部代碼塊捕獲。 本文已同步至我的個(gè)人主頁。歡迎訪問查看更多內(nèi)容!如有錯(cuò)誤或遺漏,歡迎隨時(shí)指正探討!謝謝大家的關(guān)注與支持! 一、什么是Generator函數(shù) Generator函數(shù)是ES6標(biāo)準(zhǔn)中提出的一種異步編程的解決方案。這種函數(shù)與普通函數(shù)最大的區(qū)別在于它可...
摘要:語法上,首先可以把它理解成,函數(shù)是一個(gè)狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài)。返回的遍歷器對(duì)象,可以依次遍歷函數(shù)內(nèi)部的每一個(gè)狀態(tài)。 寫在前面: 這一篇是關(guān)于ES6中生成器函數(shù)相關(guān)總結(jié)和理解... Generator函數(shù)的定義 在阮一峰老師的書中的說法是: Generator 函數(shù)有多種理解角度。語法上,首先可以把它理解成,Generator 函數(shù)是一個(gè)狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài)。執(zhí)行 Gener...
閱讀 3014·2021-11-16 11:42
閱讀 3651·2021-09-08 09:36
閱讀 950·2019-08-30 12:52
閱讀 2481·2019-08-29 14:12
閱讀 769·2019-08-29 13:53
閱讀 3583·2019-08-29 12:16
閱讀 644·2019-08-29 12:12
閱讀 2469·2019-08-29 11:16