JavaScript 是一種強大的單執行緒程式語言,廣泛用於 Web 開發。 JavaScript 中常見的挑戰是處理非同步任務,例如從 API 取得資料或執行時間敏感的操作,而不阻塞主執行緒。隨著時間的推移,開發人員已經從使用回調轉向使用 Promise,現在使用更優雅的 async/await 語法來管理非同步操作。本指南將引導您逐步了解這些概念,從基礎知識開始直到進階場景。到最後,您將能夠在現實應用程式中自信地使用非同步 JavaScript。
在 JavaScript 中,從伺服器取得資料、讀取檔案或設定逾時等任務可能需要時間才能完成。 JavaScript 允許這些任務非同步運行,而不是等待這些任務完成(這會阻止程式其餘部分的執行)。這意味著它們的處理獨立於主程式流程,允許其他程式碼立即執行。
回呼是作為參數傳遞給另一個函數的函數。當第一個函數完成其操作時,它會執行回調函數以表示完成。
function fetchData(callback) { setTimeout(() => { console.log("Data fetched!"); callback(); }, 2000); // Simulates a 2-second delay } function processData() { console.log("Processing data..."); } fetchData(processData);
說明:
使用巢狀回呼處理多個非同步任務很快就會導致程式碼不可讀且難以維護。
setTimeout(() => { console.log("Step 1: Data fetched"); setTimeout(() => { console.log("Step 2: Data processed"); setTimeout(() => { console.log("Step 3: Data saved"); }, 1000); }, 1000); }, 1000);
這個「厄運金字塔」使得調試和維護程式碼變得困難。
promise 是一個對象,表示現在、將來或永遠無法使用的值。 Promise 有三種狀態:
function fetchData(callback) { setTimeout(() => { console.log("Data fetched!"); callback(); }, 2000); // Simulates a 2-second delay } function processData() { console.log("Processing data..."); } fetchData(processData);
async/await 是承諾的語法糖,在 ES2017 中引入。它使非同步程式碼看起來是同步的,提高了可讀性和可維護性。
setTimeout(() => { console.log("Step 1: Data fetched"); setTimeout(() => { console.log("Step 2: Data processed"); setTimeout(() => { console.log("Step 3: Data saved"); }, 1000); }, 1000); }, 1000);
當需要並行執行多個獨立的非同步任務時:
function fetchData() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Data fetched!"); resolve("Fetched data"); }, 1000); }); } function processData(data) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(`Processing: ${data}`); resolve("Processed data"); }, 1000); }); } function saveData(data) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(`Saving: ${data}`); resolve("Data saved"); }, 1000); }); } // Chaining Promises fetchData() .then((data) => processData(data)) .then((processedData) => saveData(processedData)) .then((finalResult) => console.log(finalResult)) .catch((error) => console.error("Error:", error));
使用非同步函數的 try...catch 正確管理錯誤:
async function handleData() { try { const fetchedData = await fetchData(); const processedData = await processData(fetchedData); const savedData = await saveData(processedData); console.log(savedData); } catch (error) { console.error("Error:", error); } } handleData();
函數傳回一個承諾而不是解析值。這可能會導致意外行為。
async function fetchAllData() { const task1 = fetchData(); const task2 = fetchData(); const results = await Promise.all([task1, task2]); console.log("All data fetched:", results); } fetchAllData();
不,await 只能與 Promise 一起使用。然而,像 fetch 和 Node.js 的 fs.promises API 這樣的函式庫提供了基於原生 Promise 的方法。
回呼對於小型、簡單的任務或使用不支援 Promise 的舊 API 時仍然有用。
掌握非同步 JavaScript 對於任何使用現代 Web 應用程式的開發人員來說都是至關重要的。從回調開始,您可以了解 Promise 和 async/await 如何簡化非同步程式碼並提高可讀性。謹慎使用回調,利用 Promise 實現更好的錯誤處理,並擁抱 async/await 以獲得乾淨、直觀的程式碼。有了這些工具,您就可以準備好應對專案中的任何非同步挑戰。
以上是掌握非同步 JavaScript:回呼、Promise 和簡化的 Async/Await的詳細內容。更多資訊請關注PHP中文網其他相關文章!