async-await 在前端中的應用

async/await 是 ECMAScript 2017 中新增的語法糖,旨在簡化異步編程。它基於 Promise,並通過引入 async 和 await 關鍵字來使異步代碼看起來更像同步代碼。

使用 async/await

使用 async/await 的前提條件是要有異步操作,比如發起 AJAX 請求或操作 DOM。下面是一個簡單的例子,展示如何使用 async/await 發起 AJAX 請求:

async function getData(url) {
  try {
    const response = await fetch(url);
    const data = await response.json();
    return data;
  } catch (error) {
    console.error(error);
  }
}

const data = getData('https://example.com/data');
data.then((result) => console.log(result));

在上面的例子中,我們定義了一個名爲 getData 的異步函數,並將其聲明爲 async。該函數接受一個 URL 參數,使用 fetch 函數向服務器發送請求,然後等待響應。一旦響應返回,代碼就會繼續執行,解析 JSON 數據並將其返回。

注意,在 try 代碼塊中使用了 await 關鍵字,這告訴 JavaScript 引擎等待該行代碼的結果,然後繼續執行接下來的代碼。如果出現錯誤,catch 代碼塊會捕獲並處理它們。

在上述代碼中,我們調用了 getData 函數,並使用 .then() 方法處理返回值。由於 getData 函數返回一個 Promise,因此可以使用 .then() 處理它的結果。

錯誤處理

與 Promise 一樣,Async/Await 也需要正確地處理錯誤。如果一個異步操作失敗,它將返回一個拒絕(rejected)狀態的 Promise。爲了處理異步操作的錯誤,我們通常會在 try/catch 塊中使用 await

下面是一個錯誤處理的例子:

async function getData(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error(error);
  }
}

在上述代碼中,我們使用 if 語句檢查是否從服務器收到了正常響應。如果沒有,我們拋出一個錯誤。這會觸發 catch 代碼塊,允許我們處理錯誤。

並行處理異步任務

在很多情況下,我們需要同時處理多個異步任務。這時,可以使用 Promise.all() 方法來並行執行異步任務,並等待它們全部完成後再繼續執行代碼。

下面是一個例子,展示如何同時發起多個 AJAX 請求並等待它們全部完成:

async function fetchData() {
  const urls = ['https://example.com/data1', 'https://example.com/data2', 'https://example.com/data3'];
  const promises = urls.map(url => fetch(url));
  const responses = await Promise.all(promises);
  const data = await Promise.all(responses.map(response => response.json()));
  return data;
}

const data = fetchData();
data.then((result) => console.log(result));

在上述代碼中,我們首先定義了一個包含多個 URL 的數組。然後,我們使用 map() 方法將每個 URL 轉換爲一個 fetch() 方法調用,並將這些調用存儲在一個新的數組中。

接着,我們使用 Promise.all() 方法等待所有 fetch() 調用都返回結果。然後,我們使用 map() 方法將每個響應解析爲 JSON 數據,並將這些數據存儲在一個新的數組中。

最後,我們將包含所有數據的數組返回到調用方。

使用 async/await 處理動畫效果

在 Web 開發中,通常需要在 DOM 元素上應用動畫效果。使用傳統的 JavaScript 回調函數和 setTimeout() 方法來實現這些效果可能會導致出現回調地獄的問題。

通過使用 async/await,我們可以更輕鬆地在 DOM 上應用動畫效果。例如,下面是一個簡單的例子,展示如何使用 async/await 實現淡入動畫效果:

async function fadeIn(element, duration) {
  element.style.opacity = 0;
  element.style.display = 'block';
  const start = performance.now();
  while (performance.now() - start < duration) {
    const percentage = (performance.now() - start) / duration;
    element.style.opacity = Math.min(percentage, 1);
    await new Promise(resolve => requestAnimationFrame(resolve));
  }
  element.style.opacity = 1;
}

在上述代碼中,我們定義了一個名爲 fadeIn 的異步函數,並將其聲明爲 async。該函數接受兩個參數:一個 DOM 元素和一個表示動畫持續時間的數字(以毫秒爲單位)。

在函數的主體中,我們首先設置元素的初始狀態:將其不透明度設置爲 0,並將其顯示出來(通過將其 display 樣式設置爲 "block")。

接着,我們使用 performance.now() 函數獲取當前時間,並在每個幀之間進行循環。在循環內部,我們計算從動畫開始到當前幀的時間百分比,並使用該百分比來計算元素應該具有的不透明度值。然後,我們使用 requestAnimationFrame() 函數等待下一幀,並將其封裝在一個 Promise 中,以便在下一幀完成時恢復函數的執行。

最後,我們將元素的不透明度設置爲 1,以確保最終狀態正確。

結論

Async/await 是現代 JavaScript 中非常有用的功能,它使異步編程變得更加容易和直觀。除了處理 AJAX 請求外,在動畫效果和其他異步操作方面也非常有用。希望本文對您有所幫助!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/k6mmpEjLj5ptzqwE8zzZWA