Javascript生成器(Generator)的介紹與使用
什麼是生成器?
生成器是在函數內部運行的一些代碼
- 返回值後,它會自行暫停,並且——
- 調用程序可以要求取消暫停並返回另一個值
這種“返回”不是傳統的從函數 return。所以它被賦予瞭一個特殊的名稱——yield。
生成器語法因語言而異。Javascript 的生成器語法類似於 PHP,但是區別也很大,如果你希望它們的作用相同,那麼最終你會感到非常困惑。
在 javascript 中,如果想要使用生成器,則需要:
- 定義特殊的生成器函數
- 調用該函數創建一個生成器對象
- 在循環中使用該生成器對象,或直接調用其 next 方法
我們以下面這個簡單的程序做為起點,並執行以下每個步驟:
// File: sample-program.js function *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 }
下面我來解釋該程序是如何工作的。
生成器函數
首先,代碼中存在生成器函數的定義:
function* createGenerator() { for(let i=0;i<20;i++) { yield i } }
function 後面的 * 告訴 javascript 這是一個生成器函數。以下寫法都是生成器函數的有效定義。
function*createGenerator function* createGenerator function *createGenerator
* 並不是函數名的一部分。而是 function* 符號定義瞭生成器。
調用生成器函數
定義瞭生成器函數後,我們將其命名為其他名稱的函數。
// 註意:當調用時,沒有 *。 * 不是函數名稱的一部分 // `function *` 是用於定義生成器函數的符號 const generator = createGenerator()
但是要記住:createGenerator 函數沒有返回值。這是因為生成器函數沒有傳統的返回值。相反,當你直接調用生成器函數時,它總是返回實例化的 Generator 對象。
這個生成器對象具有一個 next 方法。調用 next 將在生成器函數內部運行代碼。
function* createGenerator() { for(let i=0;i<20;i++) { yield i } }
這很重要,足以再次調用它。直接調用生成器函數不會在生成器函數中運行任何代碼。而是創建一個生成器對象。它在生成器對象上調用 next,從而調用生成器函數中的代碼。
首次在生成器對象上調用 next 時,內部代碼將會一直運行,直到出現 yield 語句。一旦執行到 yield,javascript 將會暫停該代碼的執行,而 next 將返回(即給你,或yield)一個對象,該對象包含 yield 行中的值。
當你第二次(或第三次、第四次甚至更多次)再調用 next 時,代碼將會取消暫停並繼續運行(在上次調用時中斷的地方)。變量(例如本例中的 i )將會保持它的值。當代碼到達另一個 yield 語句時,該函數會再次暫停,並返回一個包含 yield 值的對象。
這就是為什麼我們要調用兩次 next
console.log(generator.next()) console.log(generator.next())
會得到以下輸出:
{ value: 0, done: false }
{ value: 1, done: false }
生成器函數中的代碼執行完畢後,將來對 next 的任何調用都會返回一個對象,該對象的值為 undefined 且done 設置為 true。
{ value: undefined, done: true }
生成器和循環
雖然可以在生成器對象上手動調用 next,但我們主要是要在循環中使用。看一下這個稍作修改的程序。
// File: sample-program.js @highlightsyntax@jscript function *createGenerator() { for(let i=0;i<5;i++) { yield i } } const generator = createGenerator() for(const value of generator) { console.log(value) }
當在 for…of 循環中使用生成器對象時,每次循環都會在生成器對象上調用 next,並用產生的值填充變量(上面的 value)。運行該程序將會輸出以下內容:
$ node sample-program.js
0
1
2
3
4
在下一篇文章中,我們將更深入地探討 for … of 循環,並探索怎樣為 javascript 提供一種內置方法來循環 javascript 中的任何對象。
總結
到此這篇關於Javascript生成器(Generator)的文章就介紹到這瞭,更多相關Javascript生成器(Generator)內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Node.js中的異步生成器與異步迭代詳解
- JavaScript Generator異步過度的實現詳解
- JavaScript前端迭代器Iterator與生成器Generator講解
- 詳解ES6 中的迭代器和生成器
- ES6的循環與可迭代對象示例詳解