總結:Generator函數是一種特殊的函數,可以使用關鍵字yield和next( )實現暫停和繼續執行,而關鍵字yield*專門用於調用Generator函數,看似簡單的特性,在實際開發中卻有極大的用處。

ES6給我們帶來的一種新函數,在學習它之前,希望你已經閱讀並初步了解了上一節的內容:iterator遍歷器。

1、聲明Generator函數

我們要學習的這個新函數叫做:Generator函數,又稱生成器函數,是ES6的一個重要的新特性。

我們來看看這個函數張什麼模樣:

  1. 普通函數用function來聲明,Generator函數用function*聲明。
  2. Generator函數內部有新的關鍵字:yield,普通函數沒有。

PS:函數體內用到了ES6的新特性:字元串模板。第六節的內容,點擊可以查看。

了解了Generator函數的聲明方式,我們又多了兩個疑問:

  1. Generator函數運行起來會發生什麼?
  2. 關鍵字yield語句的作用是什麼?

二、調用Generator函數

看到這裡有沒有發現,這裡生成器的next( )方法的和遍歷器iterator的next( )方法的返回結果是不是一樣?

沒錯,你可以把Generator函數被調用後得到的生成器理解成一個遍歷器iterator,用於遍歷函數內部的狀態

(1)Generator函數的行為

通過上面的案例,我們知道了:Generator函數被調用後並不會一直執行到最後,它是先回返回一個生成器對象,然後hold住不動,等到生成器對象的next( )方法被調用後,函數才會繼續執行,直到遇到關鍵字yield後,又會停止執行,並返回一個Object對象,然後繼續等待,直到next( )再一次被調用的時候,才會繼續接著往下執行,直到done的值為true。

(2)yield語句的作用

而yield在這裡起到了十分重要的作用,就相當於暫停執行並且返回信息。有點像傳統函數的return的作用,但不同的是普通函數只能return一次,但是Generator函數可以有很多個yield。而return代表的是終止執行,yield代表的是暫停執行,後續通過調用生成器的next( )方法,可以恢復執行

(3)next( )方法接收參數

next( )方法還可以接受一個參數,它的參數會作為上一個yield的返回值,我們來看一下:

注意函數體內的第一個yield關鍵字,我們把它的返回值賦值給了一個變數res。

再看2次next方法的調用:

第1次調用next( )方法,返回的對象屬性value值為「hello」,屬性done值為:fasle,並暫停執行。

第2次next( )方法,傳入參數:字元串「前端君」。此時,第二個yield關鍵字緊跟著的是變數res,而變數res的值正是上一個關鍵字yield的返回值。也就是說這個值正是我們傳入的參數:「qiaoying」。因為:next( )的參數會作為上一個yield的返回值。

慢慢體會一下,理清邏輯,稍微有點繞。

(4)關鍵字yield*

我們主要看start( )這個Generator函數,其中有兩句代碼:

這裡使用了關鍵字yield*來實現調用另外兩個Generator函數。從後面的多個next( )方法得到的結果看,我們可以知道:

如果一個Generator函數A執行過程中,進入(調用)了另一個Generator函數B,那麼會一直等到Generator函數B全部執行完畢後,才會返回Generator函數A繼續執行。

三、Generator函數的用途

以上就是對Generator函數的講解介紹,它是ES6的一個很重要的新特性。它可以控制函數的內部狀態,依次遍歷每個狀態;可以根據需要,輕鬆地讓函數暫停執行或者繼續執行。

根據這個特點,我們可以利用Generator函數來實現非同步操作的效果。

原理是:利用Generator函數暫停執行的作用,可以將非同步操作的語句寫到yield後面,通過執行next方法進行回調。


推薦閱讀:
相关文章