iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0

聯繫我

如果有任何問題或建議,歡迎隨時聯繫我:

介紹

今天我們來到第 27 天,話題是「簡化異步處理」!說到 JavaScript 的異步處理,你可能會聯想到回調地獄(Callback Hell)、Promise chain(Promise 鏈),以及最近幾年廣受歡迎的 async/await 語法。這些工具讓我們處理異步代碼時更加輕鬆,不再需要深陷於嵌套的回調地獄中。今天我們將重點講解如何使用 async/await 和一些簡單的技巧,讓你在處理異步操作時更加高效。

為什麼需要異步處理?

JavaScript 是單線程的,這意味著它同一時間只能做一件事。假設你在處理一個大型文件或等待網路請求的響應,如果不使用異步處理,這些操作可能會讓你的應用程式“卡住”,無法回應其他操作。

異步的現實生活比喻

想像一下你在點餐排隊,但你還要等廚房完成食物。你可以選擇一直站在櫃台前等(同步操作),但這樣會讓櫃台後面的人無法點餐。相反,你可以選擇回到座位上,等待號碼叫到你再去取餐(異步操作)。這樣,你不僅節省了時間,櫃台也可以繼續處理其他客人的訂單。

async/await 的簡化異步處理

async 函數

async 關鍵字用來定義一個異步函數,這個函數會返回一個 Promise。所有返回非 Promise 的值會被自動封裝成 Promise

async function fetchData() {
  return "Fetched data";
}

fetchData().then(data => {
  console.log(data); // 輸出: Fetched data
});

在這裡,fetchData 函數被標記為 async,它返回一個 Promise,這樣我們就可以使用 .then() 來處理它的結果。

await 等待 Promise 的結果

await 關鍵字只能在 async 函數中使用,它可以暫停函數的執行,直到 Promise 完成。await 會等待 Promise 的結果,而不是立即返回。

async function processData() {
  const data = await fetchData(); // 等待 fetchData 的結果
  console.log(data); // 輸出: Fetched data
}

processData();

await 就像告訴 JavaScript:「別著急,等這個 Promise 完成了再繼續執行。」

異步錯誤處理

async/await 語法中,我們可以使用 try...catch 來捕捉異步操作中的錯誤。

示例:處理異步操作中的錯誤

async function fetchDataWithErrorHandling() {
  try {
    const data = await fetch("https://invalid-url.com"); // 這裡可能會拋出錯誤
    console.log(data);
  } catch (error) {
    console.error("Error fetching data:", error); // 捕捉到錯誤
  }
}

fetchDataWithErrorHandling();

當異步操作失敗時,我們可以用 catch 來捕獲並處理錯誤。這樣就不會中斷整個應用程式的運行。

並行處理多個異步操作

有時候我們可能需要同時執行多個異步操作。此時我們可以使用 Promise.all(),讓所有操作同時進行,最後等待所有操作完成。

示例:使用 Promise.all() 執行並行異步操作

async function fetchMultipleDataSources() {
  const [data1, data2] = await Promise.all([
    fetch("https://api.example.com/data1"),
    fetch("https://api.example.com/data2")
  ]);

  console.log("Data 1:", data1);
  console.log("Data 2:", data2);
}

fetchMultipleDataSources();

Promise.all() 可以同時發出多個請求,並且等所有請求都完成後才繼續執行。這樣可以大大提升應用性能。

實際應用場景

加載數據並顯示加載動畫

在現實的應用中,我們可能會希望在數據加載時顯示一個加載動畫,這可以通過 async/await 簡單實現:

async function loadData() {
  showLoading(); // 顯示加載動畫

  try {
    const data = await fetchData(); // 加載數據
    displayData(data); // 顯示數據
  } catch (error) {
    displayError(error); // 處理錯誤
  } finally {
    hideLoading(); // 隱藏加載動畫
  }
}

loadData();

這樣的設計不僅讓代碼簡潔直觀,也提升了用戶體驗。

本篇自我挑戰

何謂自我挑戰,問題不怕困難,重點是要解決出問題的人(誤,嘗試開始! 在這裡你可以看到大家是怎麼回答題目的,甚至會看到暗藏的高手可以將簡單的題目回答的淋漓盡致!
回答我都會放在隔天的 GitHub Day28 JS 上哦!

挑戰 1: 使用 async/await 處理一個簡單的 API 請求

? function fetchData() {
  const response = ? fetch("https://api.example.com/data");
  const data = ? response.json();
  console.log(data);
}

fetchData();

挑戰 2: 使用 Promise.all() 同時加載多個數據源

? function fetchDataFromMultipleSources() {
  const [data1, data2] = ?([
    fetch("https://api.example.com/data1").then(res => res.json()),
    fetch("https://api.example.com/data2").then(res => res.json())
  ]);

  console.log("數據來源 1:", data1);
  console.log("數據來源 2:", data2);
}

fetchDataFromMultipleSources();

總結

今天我們學習了如何使用 async/await 簡化異步操作,並且了解了如何處理多個並行的異步操作。

繼續加油!明天我們將探索進階的正則表達式技巧!


上一篇
【Day 26】高階函數:map、filter、reduce
下一篇
【Day 28】進階正則表達式技巧
系列文
JavaScript 新手到高手:現代特性全攻略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言