JS 中 async/await 功能介紹與使用演示
一、功能介紹
-
基本概念
async
:用于聲明異步函數,返回一個Promise
對象。即使函數內沒有顯式返回Promise
,也會隱式將返回值封裝為Promise.resolve()
。await
:僅能在async
函數內部使用,用于等待Promise
對象的解析(resolve
)或拒絕(reject
)。它使異步代碼看起來類似同步代碼,提升可讀性。
-
核心特性
- 異步流程同步化:通過
await
暫停函數執行,直到Promise
完成,再繼續后續邏輯。 - 錯誤傳播:若
await
后的Promise
被拒絕(reject
),會拋出錯誤,需用try/catch
捕獲。 - 兼容性:
async/await
是 ES2017 引入的語法糖,底層基于Promise
,兼容現代瀏覽器和 Node.js。
- 異步流程同步化:通過
-
使用場景
- 替代回調函數和
.then()
鏈式調用,處理異步操作(如 API 請求、文件讀寫)。 - 串行或并行執行多個異步任務,優化代碼結構。
- 替代回調函數和
二、使用演示
-
基礎示例:順序執行異步任務
// 模擬異步請求函數 function fetchData(url) {return new Promise((resolve) => {setTimeout(() => {resolve(`Data from ${url}`);}, 1000);}); }// 使用 async/await 順序執行 async function fetchSequentially() {try {const data1 = await fetchData('api1');console.log(data1); // Data from api1const data2 = await fetchData('api2');console.log(data2); // Data from api2} catch (error) {console.error('Error:', error);} }fetchSequentially();
-
并發執行異步任務
使用Promise.all
并行處理多個請求,減少總耗時:async function fetchConcurrently() {try {const [data1, data2] = await Promise.all([fetchData('api1'),fetchData('api2')]);console.log(data1, data2); // 同時輸出兩個結果} catch (error) {console.error('Error:', error);} }fetchConcurrently();
-
錯誤處理
結合try/catch
捕獲異步錯誤:async function fetchWithErrorHandling() {try {const response = await fetch('https://invalid.url');const data = await response.json(); // 如果響應失敗,此處會拋錯} catch (error) {console.error('Caught error:', error);} }fetchWithErrorHandling();
-
實用場景:模擬延遲執行
實現休眠函數:function delay(ms) {return new Promise((resolve) => setTimeout(resolve, ms)); }async function delayedTask() {console.log('Task started');await delay(2000); // 暫停2秒console.log('Task completed'); }delayedTask();
三、注意事項
-
await
的局限性- 只能在
async
函數內使用,否則會拋出語法錯誤。 - 后面可以是任意表達式(如字符串、數值),非
Promise
會被自動封裝為Promise.resolve()
。
- 只能在
-
錯誤處理
- 未捕獲的
reject
會導致async
函數返回的Promise
變為reject
狀態,需用try/catch
或.catch()
處理。
- 未捕獲的
-
性能優化
- 避免過度串行:連續使用
await
會導致異步任務串行執行,降低性能。可改用Promise.all
并發處理無關依賴的任務。 - 不要阻塞主線程:長時間同步操作(如循環)中濫用
await
可能阻塞渲染,需謹慎設計異步流程。
- 避免過度串行:連續使用
四、總結
async/await
是 JavaScript 異步編程的語法糖,本質是基于 Promise
,但提供了更簡潔、易讀的代碼風格。它適用于大多數異步場景,尤其適合需要順序執行或并發控制的場景。使用時需注意錯誤處理和性能優化,避免陷入同步思維的誤區。