首頁 > web前端 > js教程 > 詳解Javascript中的Generator生成器

詳解Javascript中的Generator生成器

青灯夜游
發布: 2021-01-02 09:26:17
轉載
2665 人瀏覽過

詳解Javascript中的Generator生成器

什麼是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 的任何呼叫都會傳回一個對象,該對象的值為undefineddone 設定為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 中的任何物件

英文原文網址:https://alanstorm.com/javascript-generators/

作者:Alan Storm

#譯文網址:https://segmentfault.com/a/1190000023924834

更多程式相關知識,請造訪:程式設計入門! !

以上是詳解Javascript中的Generator生成器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板