Javascript生成器(Generator)的介紹與使用
生成器是在函數(shù)內(nèi)部運行的一些代碼
返回值后,它會自行暫停,并且—— 調(diào)用程序可以要求取消暫停并返回另一個值這種“返回”不是傳統(tǒng)的從函數(shù) return。所以它被賦予了一個特殊的名稱——yield。
生成器語法因語言而異。Javascript 的生成器語法類似于 PHP,但是區(qū)別也很大,如果你希望它們的作用相同,那么最終你會感到非常困惑。
在 javascript 中,如果想要使用生成器,則需要:
定義特殊的生成器函數(shù) 調(diào)用該函數(shù)創(chuàng)建一個生成器對象 在循環(huán)中使用該生成器對象,或直接調(diào)用其 next 方法我們以下面這個簡單的程序做為起點,并執(zhí)行以下每個步驟:
// File: sample-program.jsfunction *createGenerator() { for(let i=0;i<20;i++) { yield i }}const generator = createGenerator()console.log(generator.next())console.log(generator.next())
如果運行這段代碼,則會得到以下輸出:
$ node sample-program.js
{ value: 0, done: false }{ value: 1, done: false }
下面我來解釋該程序是如何工作的。
生成器函數(shù)首先,代碼中存在生成器函數(shù)的定義:
function* createGenerator() { for(let i=0;i<20;i++) { yield i }}
function 后面的 * 告訴 javascript 這是一個生成器函數(shù)。以下寫法都是生成器函數(shù)的有效定義。
function*createGeneratorfunction* createGeneratorfunction *createGenerator
* 并不是函數(shù)名的一部分。而是 function* 符號定義了生成器。
調(diào)用生成器函數(shù)定義了生成器函數(shù)后,我們將其命名為其他名稱的函數(shù)。
// 注意:當(dāng)調(diào)用時,沒有 *。 * 不是函數(shù)名稱的一部分// `function *` 是用于定義生成器函數(shù)的符號const generator = createGenerator()
但是要記住:createGenerator 函數(shù)沒有返回值。這是因為生成器函數(shù)沒有傳統(tǒng)的返回值。相反,當(dāng)你直接調(diào)用生成器函數(shù)時,它總是返回實例化的 Generator 對象。
這個生成器對象具有一個 next 方法。調(diào)用 next 將在生成器函數(shù)內(nèi)部運行代碼。
function* createGenerator() { for(let i=0;i<20;i++) { yield i }}
這很重要,足以再次調(diào)用它。直接調(diào)用生成器函數(shù)不會在生成器函數(shù)中運行任何代碼。而是創(chuàng)建一個生成器對象。它在生成器對象上調(diào)用 next,從而調(diào)用生成器函數(shù)中的代碼。
首次在生成器對象上調(diào)用 next 時,內(nèi)部代碼將會一直運行,直到出現(xiàn) yield 語句。一旦執(zhí)行到 yield,javascript 將會暫停該代碼的執(zhí)行,而 next 將返回(即給你,或yield)一個對象,該對象包含 yield 行中的值。
當(dāng)你第二次(或第三次、第四次甚至更多次)再調(diào)用 next 時,代碼將會取消暫停并繼續(xù)運行(在上次調(diào)用時中斷的地方)。變量(例如本例中的 i )將會保持它的值。當(dāng)代碼到達(dá)另一個 yield 語句時,該函數(shù)會再次暫停,并返回一個包含 yield 值的對象。
這就是為什么我們要調(diào)用兩次 next
console.log(generator.next())console.log(generator.next())
會得到以下輸出:
{ value: 0, done: false }{ value: 1, done: false }
生成器函數(shù)中的代碼執(zhí)行完畢后,將來對 next 的任何調(diào)用都會返回一個對象,該對象的值為 undefined 且done 設(shè)置為 true。
{ value: undefined, done: true }生成器和循環(huán)
雖然可以在生成器對象上手動調(diào)用 next,但我們主要是要在循環(huán)中使用。看一下這個稍作修改的程序。
// File: sample-program.js@highlightsyntax@jscriptfunction *createGenerator() { for(let i=0;i<5;i++) { yield i }}const generator = createGenerator()for(const value of generator) { console.log(value)}
當(dāng)在 for...of 循環(huán)中使用生成器對象時,每次循環(huán)都會在生成器對象上調(diào)用 next,并用產(chǎn)生的值填充變量(上面的 value)。運行該程序?qū)敵鲆韵聝?nèi)容:
$ node sample-program.js01234
在下一篇文章中,我們將更深入地探討 for ... of 循環(huán),并探索怎樣為 javascript 提供一種內(nèi)置方法來循環(huán) javascript 中的任何對象。
總結(jié)到此這篇關(guān)于Javascript生成器(Generator)的文章就介紹到這了,更多相關(guān)Javascript生成器(Generator)內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. JSP之表單提交get和post的區(qū)別詳解及實例2. asp讀取xml文件和記數(shù)3. Xml簡介_動力節(jié)點Java學(xué)院整理4. 低版本IE正常運行HTML5+CSS3網(wǎng)站的3種解決方案5. JSP+Servlet實現(xiàn)文件上傳到服務(wù)器功能6. ASP常用日期格式化函數(shù) FormatDate()7. UDDI FAQs8. 將properties文件的配置設(shè)置為整個Web應(yīng)用的全局變量實現(xiàn)方法9. HTML <!DOCTYPE> 標(biāo)簽10. CSS可以做的幾個令你嘆為觀止的實例分享
