1. 程式人生 > >javascript未來的函式:生成器和promise

javascript未來的函式:生成器和promise

1.通過生成器讓函式持續執行。

2.使用promise處理非同步任務。

3.使用生成器和promise書寫優雅程式碼。

ES6語言特性:生成器(generator)和promise(promise)

生成器(generator)是一種特殊型別的函式。當從頭到尾執行標準函式時,它最多隻生成一個值。然而生成器函式會在幾次執行請求中暫停,因此每次執行都可能會生成一個值。雖然生成器對JavaScript來說是一個新特性,其實它已經在Python、PHP和C#中存在很長時間了。

如何使用生成器?如何使用生成器來簡化複雜迴圈,如何利用生成器的能力來掛起和恢復迴圈的執行,這些技巧都能幫助你寫出更簡單、更優雅的非同步程式碼。

物件的一個新的內建型別promise,也能幫你編寫非同步程式碼。promise物件是一個佔位符,暫時替代那些尚未計算出來但未來會計算出的值。對於多個非同步操作來說,使用promise物件是非常有好處的。

你知道嗎?

1.生成器函式的主要用途是什麼?

2.在非同步程式碼中,為什麼使用promise比使用簡單的回撥函式更好?

3.使用Promise.race來執行很多長期執行的任務,promise最終會在上面時候變成resolved狀態?它什麼時候會無法變成resolved狀態?

使用生成器和promise編寫優雅的非同步程式碼

由於JavaScript依賴於單執行緒執行模型,如果需要從伺服器獲取資料是一個長時間操作,所以會出現在耗時操作結束之前,UI渲染會暫停,最終造成應用無響應。。當然可以使用回撥解決上述問題,但是這樣程式碼會很散亂,其中包括很多錯誤處理的樣板程式碼。我們可以使用生成器函式和promise大顯身手了。

console.log("--------------------使用生成器和promise編寫優雅的非同步程式碼-------------");

async(function* () {

try{

//通過在function關鍵字後藏家一個*號碼可以定義生成器函式。在生成器函式中可以使用新的yield關鍵字

//promises物件都隱含在了getJSON方法中,所以比起非阻塞回調函式程式碼,使用生成器和promise明顯更為優雅。

const ninjas = yield getJSON('ninjas.json');

const missions = yield getJSON(ninjas[0].missionsUrl);

const missionDescription = yield getJSON(missions[0].detailsUrl);

} catch (e) {

 

}

});

生成器函式幾乎是一個完全嶄新的函式型別,他和標準的普通函式完全不同。生成器(generator)函式能生成一組值的序列,但每個值的生成是基於每次請求,並不同於標準函式那樣立即生成。我們必須顯示地向生成器請求一個新的值,隨後生成器要麼響應一個新生成的值,要麼就告訴我們它之後不會再生成新值。每當生成器函式生成了一個值,它都不會像普通函式一樣停止執行。相反,生成器幾乎不掛起。隨後,當對另一個值的請求到來後,生成器就會從上次離開的位置恢復執行。

 

console.log("------------使用生成器函式生成一些列值--------------------");
//通過在關鍵字function後面新增星號*,定義生成器函式
function* WeaponGenerator() {
  //使用新的關鍵字yield生成獨立的值
  yield "Katana";
  yield "Wakizashi";
  yield "Kusarigama";
}
//使用新的迴圈型別for-of取出生成的值序列
for (let weapon of WeaponGenerator()) {
  if (weapon !== undefined) {
    console.log("weapon:" + weapon);
  }
}

 

首先定義了一個生成器,它能夠生產一些列weapon的資料,建立一個生成器函式非常簡單:僅僅需要在關鍵字function後面加上一個星號(*)。這樣一來生成器函式體內就能夠使用新關鍵字yield,從而生成獨立的值。

 

 

建立了一個叫做WeaponGenerator的生成器,其用於生成一系列weapon資料:Katana、Wakizashi和Kusarigama。作為取出weapon資料序列值的方法之一,

for-of是一種用於迴圈結構新型別:

//使用新的迴圈型別for-of取出生成的值序列

for (let weapon of WeaponGenerator()) {

if (weapon !== undefined) {

console.log("weapon:" + weapon);

}

}

 

我們把執行生成器得到的結果放在for-of迴圈的右邊。如果觀察WeaponGenerator函式的函式體,發現沒有return語句。這是為什麼?這個例子中,for-of迴圈的右邊不是應該得到undefined,就像我們處理一個標準函式一樣嗎?真相是生成器函式和標準函式非常不同。對於初學者來說,呼叫生成器並不會執行生成器函式,相反,它會建立一個叫迭代器(iterator)的物件。

 

參考《JavaScript忍者祕籍》