JavaScript 的非同步特性對於現代 Web 開發來說既強大又必不可少。從從 API 取得資料到處理使用者輸入,非同步操作很常見,並且需要高效率的處理。 ECMAScript 6 (ES6) 中引入的Promises 和ECMAScript 2017 中的Async/Await 徹底改變了開發人員處理非同步程式碼的方式,使其更乾淨、更具可讀性。
在本部落格中,我們將探討 Promises 和 Async/Await、它們的工作原理以及何時在 JavaScript 專案中使用它們。
JavaScript 是單執行緒的,這表示一次只能執行一個動作。然而,諸如網路請求、檔案讀取或計時器之類的非同步操作允許 JavaScript 處理原本會阻塞主執行緒的任務,使其對使用者操作的回應更加靈敏。
在Promises和Async/Await之前,非同步操作是使用回呼來處理的,這常常導致回調地獄 - 深度嵌套且難以維護的回調結構。
A Promise 是一個表示非同步操作最終完成(或失敗)的物件。與回調相比,它允許您以更結構化的方式處理非同步任務。 Promise 可以處於以下三種狀態之一:
要建立一個 Promise,您需要傳入一個有兩個參數的函數:resolve 和reject。在 Promise 中,您執行非同步任務,並根據結果呼叫「resolve」(成功時)或「reject」(失敗時)。
const fetchData = () => { return new Promise((resolve, reject) => { setTimeout(() => { const data = { name: 'Ishan', age: 25 }; resolve(data); }, 1000); }); };
在上面的範例中,fetchData 函數傳回一個承諾,該承諾將在 1 秒後解析所取得的資料。
您可以使用 .then() 來處理承諾的結果(如果成功),使用 .catch()(如果發生錯誤)。
fetchData() .then(data => { console.log(data); // { name: 'Ishan', age: 25 } }) .catch(error => { console.error('Error:', error); });
Promise 最強大的功能之一是它們能夠連結多個非同步操作。一個 .then() 的結果可以傳遞給下一個。
fetchData() .then(data => { return data.name.toUpperCase(); // Modify data }) .then(upperName => { console.log(upperName); // 'ISHAN' }) .catch(error => { console.error('Error:', error); });
Promise 還具有內建的組合器方法,可以幫助同時處理多個非同步操作。
Promise.all([fetchData(), fetchData()]) .then(results => console.log(results)) .catch(error => console.error(error));
Promise.race([fetchData(), fetchData()]) .then(result => console.log(result)) .catch(error => console.error(error));
雖然 Promise 有助於建立非同步程式碼,但在處理多個非同步操作時,連結 .then() 呼叫仍然會變得複雜。這就是 Async/Await 的用武之地。 async/await 在 ES2017 中引入,讓您可以編寫看起來同步的非同步程式碼。
要使用 async/await,請將函數標記為 async,並在函數內,在 Promise 之前使用 wait 關鍵字。這使得 JavaScript 在繼續之前等待承諾解決(或拒絕)。
const fetchData = () => { return new Promise((resolve) => { setTimeout(() => { resolve({ name: 'Ishan', age: 25 }); }, 1000); }); }; const getData = async () => { const data = await fetchData(); console.log(data); // { name: 'Ishan', age: 25 } }; getData();
請注意,與連結 .then() 呼叫相比,此程式碼要簡潔得多。它讀起來像同步程式碼,但非同步工作。
使用 async/await 時,可以使用 try/catch 處理錯誤,這比使用具有 Promise 的 .catch() 更容易管理錯誤。
const getData = async () => { try { const data = await fetchData(); console.log(data); } catch (error) { console.error('Error:', error); } }; getData();
這種方法使錯誤處理更加可預測,並將所有邏輯保留在一個程式碼區塊中。
Promise 和 async/await 都實現了處理非同步操作的相同目標。那麼,什麼時候應該使用其中一種而不是另一種呢?
以下情況使用 Promise:
在下列情況下使用非同步/等待:
One of the advantages of async/await is that it can be combined with promise combinators like Promise.all() to handle multiple asynchronous operations simultaneously.
const fetchData1 = () => { return new Promise(resolve => setTimeout(() => resolve('Data 1'), 1000)); }; const fetchData2 = () => { return new Promise(resolve => setTimeout(() => resolve('Data 2'), 2000)); }; const getAllData = async () => { try { const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]); console.log(data1, data2); // 'Data 1', 'Data 2' } catch (error) { console.error('Error:', error); } }; getAllData();
This approach allows you to run promises in parallel while still benefiting from the simplicity of async/await.
Promises and Async/Await are essential tools for managing asynchronous code in JavaScript. While promises provide a structured way to handle async tasks, async/await takes it to the next level by offering a cleaner and more readable syntax. Both approaches have their place, and knowing when to use them will make you a more efficient and effective JavaScript developer.
If you're new to asynchronous JavaScript, start with promises and experiment with async/await to see how they can transform the way you write code.
The above is the detailed content of Mastering Asynchronous JavaScript: A Guide to Promises and Async/Await. For more information, please follow other related articles on the PHP Chinese website!