JavaScript Async / Await在10分鐘內解釋

在最長的時間裏,JavaScript開發人員不得不依賴回調來處理異步代碼。
結果,咱們中的許多人都經歷過回調地獄...

謝天謝地,而後(或者咱們應該說 .then)來了Promises。他們爲回調提供了更有組織的替代方案,而且大多數社區很快轉而使用它們。如今,隨着最新添加的Async / Await,編寫JavaScript代碼即將變得更好!

什麼是async/await?

async- 聲明一個異步函數(async function someName(){...})

  1. 自動將常規函數轉換爲Promise;
  2. 當被調用的異步函數解析爲它們體內返回的內容時;
  3. 異步功能可使用await

await - 暫停執行異步功能。(var result = await someAsyncCall();)

  1. 當置於Promise調用以前時,await強制其他代碼等待Promise完成並返回結果;
  2. Await僅適用於Promises,它不適用於回調;
  3. Await只能在 async 函數內部使用

下面一個簡單的例子,但願可以解決問題:
javascript

假設咱們想從服務器獲取一些JSON文件。咱們將編寫一個使用axios庫併發送HTTP GET請求
的函數https://tutorialzine.com/misc/files/example.json。咱們必須等待服務器響應,所以這個HTTP請求天然會是異步的。

咱們將看到兩次執行相同的功能。首先使用Promise,而後第二次使用Async / Await
java

// Promise

function getJSON(){

    // 建立一個Promise
    return new Promise( function(resolve) {
        axios.get('https://tutorialzine.com/misc/files/example.json')
            .then( function(json) {
                // 請求的數據用resolve返回結果
                resolve(json);
            });
    });

}

// Async/Await 

// async關鍵字將自動建立並返回 Promise
async function getJSONAsync(){
    // wait關鍵字使咱們沒必要編寫.then()塊
    let json = await axios.get('https://tutorialzine.com/misc/files/example.json');
    // 請求的結果賦值給json變量並返回
    return json;
}複製代碼

很明顯,代碼的Async / Await版本更短,更容易閱讀。除了使用的語法以外,兩個函數徹底相同 - 它們都返回Promises並使用axios的JSON響應來解析。咱們能夠像這樣調用咱們的異步函數:

getJSONAsync()。thenfunction(result) {
     //用result作一些事情。 
});複製代碼

Async / Await是否會使Promise過期

不會。使用Async / Await時,咱們仍在使用Promise。甚至有一些用例Async / Await沒有削減它,咱們不得不回到Promises尋求幫助。一個這樣的場景是當咱們須要進行多個獨立的異步調用並等待全部這些調用完成時。ios

若是咱們嘗試使用async和await執行此操做,將發生如下狀況:

async function getABC() {
  let A = await getValueA(); // getValueA須要2秒才能完成
  let B = await getValueB(); // etValueB須要4秒才能完成
  let C = await getValueC(); // getValueC須要3秒才能完成

  return A*B*C;
}複製代碼

每一個等待調用將等待前一個返回結果。因爲咱們一次只進行一次調用,整個功能從開始到結束須要9秒(2 + 4 + 3)。

這不是一個最佳的解決方案,由於這三個變量 AB以及 C不依賴於彼此。換句話說,咱們不須要知道 A以前的價值 B。咱們能夠同時得到它們而且等待幾秒鐘。要在同一時間發送全部請求, Promise.all()則須要。這將確保在繼續以前咱們仍然擁有全部結果,但異步調用將並行觸發,而不是一個接一個地觸發。

async function getABC() {
  // Promise.all() 容許同時發送全部請求。
  let results = await Promise.all([ getValueA, getValueB, getValueC ]); 
  return results.reduce((total,value) => total * value);
}複製代碼

這樣,該功能將花費更少的時間。GetValueA和GetValueC調用將在GetValueB時完成。咱們將有效地將執行時間減小到最慢請求的時間(getValueB - 4秒),而不是時間的總和。

處理Async / Await中的錯誤

Async / Await的另外一個好處是它容許咱們在一個好的舊try / catch塊中捕獲任何意外錯誤。
咱們只須要 await像這樣包裝咱們的調用:

async function doSomethingAsync(){
    try {
        // 此異步調用可能會失敗。
        let result = await someAsyncCall();
    }
    catch(error) {
        // 若是失敗,將在這裏捕獲錯誤
    }  
}複製代碼

catch子句將處理由等待的異步調用或咱們可能在try塊內寫入的任何其餘失敗代碼引起的錯誤。
json

若是狀況須要,咱們還能夠在執行異步函數時捕獲錯誤。由於全部異步函數都返回Promise,因此在調用它們時咱們能夠簡單地包含一個.catch()事件處理程序。
axios

// 沒有try / catch塊的異步函數

async function doSomethingAsync(){
    // 此異步調用可能會失敗
    let result = await someAsyncCall();
    return result;  
}

// 在調用該函數捕獲錯誤。
doSomethingAsync().
    .then(successHandler)
    .catch(errorHandler);複製代碼

選擇你喜歡的錯誤處理方法並堅持下去是很重要的。同時使用try/catch和.catch()極可能會致使問題。瀏覽器

瀏覽器支持

Async / Await已在大多數主流瀏覽器中提供。這僅排除IE11 - 全部其餘供應商將識別您的異步/等待代碼,而無需外部庫。


                                                         異步/等待瀏覽器支持bash


參考文獻:tutorialzine.com/2017/07/jav…服務器

相關文章
相關標籤/搜索