:async/await)
一、什么是 async/await在 Node.js 中async/await 是一種處理異步操作的語法糖。async/await 基于 Promise但讓異步代碼看起來更像同步代碼極大地提高了代碼的可讀性和可維護性。async關鍵字用于聲明一個函數是異步的而await關鍵字用于等待一個 Promise 的解決resolve或拒絕reject。使用 async/await 可以避免回調地獄callback hell并使錯誤處理更加直觀。二、基本語法async 函數任何函數都可以通過添加async關鍵字變成異步函數async function myFunction() { return Hello World; } // 等價于 function myFunction() { return Promise.resolve(Hello World); }async函數總是返回一個 Promise。如果返回值不是 Promise它會被自動包裝成 Promise。await 表達式await只能在async函數內部使用它會暫停函數的執行等待 Promise 解決然后繼續執行并返回結果async function fetchData() { const response await fetch(https://api.example.com/data); const data await response.json(); return data; }三、錯誤處理try/catch 方式處理 async/await 錯誤最常用的方法是使用try/catchasync function getUser() { try { const response await fetch(https://api.example.com/user); const user await response.json(); return user; } catch (error) { console.error(Error fetching user:, error); throw error; // 可以選擇重新拋出錯誤 } }直接處理 Promise你也可以直接處理返回的 PromisegetUser() .then(user console.log(user)) .catch(error console.error(error));四、實際應用示例并行執行多個異步操作使用Promise.all結合 async/await 可以并行執行多個異步操作async function fetchMultipleUrls(urls) { try { const requests urls.map(url fetch(url)); const responses await Promise.all(requests); const data await Promise.all(responses.map(r r.json())); return data; } catch (error) { console.error(Error fetching data:, error); throw error; } } // 使用 const data await fetchMultipleUrls([ https://api.example.com/users, https://api.example.com/posts ]);順序執行 vs 并行執行順序執行較慢適合有依賴關系的操作async function sequentialTasks() { const user await getUser(); // 等待完成 const posts await getPosts(); // 再執行下一個 return { user, posts }; }并行執行較快適合獨立的操作async function parallelTasks() { const userPromise getUser(); const postsPromise getPosts(); const [user, posts] await Promise.all([userPromise, postsPromise]); return { user, posts }; }數據庫操作示例async function getUserAndPosts(userId) { try { const user await User.findById(userId); const posts await Post.find({ userId }); return { user, posts }; } catch (error) { console.error(Database error:, error); throw error; } }文件操作示例const fs require(fs).promises; async function readFiles() { try { const data1 await fs.readFile(file1.txt, utf8); const data2 await fs.readFile(file2.txt, utf8); console.log(Data:, data1, data2); } catch (err) { console.error(讀取文件出錯:, err); } }五、最佳實踐實踐說明總是處理錯誤不要忽略 await 可能拋出的錯誤使用 try/catch 或.catch()處理避免不必要的 await如果不需要等待結果可以直接返回 Promise合理使用并行多個獨立的異步操作應該并行執行使用Promise.all保持代碼清晰避免過深的 async/await 嵌套必要時提取函數注意性能影響每個 await 都會暫停函數執行在循環中要特別注意六、常見問題async/await 與 Promise 的關系async/await 是建立在 Promise 之上的語法糖。任何async函數都返回 Promise任何await后面都可以接 Promise。// async/await 和 Promise 可以混用 async function processUser() { const user await getUser(); const posts await getPosts(user.id); return posts; // 等價于 return Promise.resolve(posts) } // 返回的異步函數本身就是 Promise processUser().then(posts console.log(posts));為什么我的 async 函數返回 undefined這可能是因為忘記在 await 前使用return或者在 Promise 解決前函數就退出了。// 錯誤示例沒有 return返回 undefined async function getData() { await fetch(url); // 沒有 return } // 正確示例使用 return async function getData() { return await fetch(url); } // 或者直接返回 Promise async function getData() { return fetch(url); // 自動包裝為 Promise }可以在頂層使用 await 嗎在ES 模塊中文件以.mjs結尾或package.json中type: module可以直接在頂層使用await。在 CommonJS 模塊中需要包裹在 async 函數中。// ES 模塊中可以直接使用頂層 await const data await fetchData(); console.log(data); // CommonJS 模塊中需要包裹 (async () { const data await fetchData(); console.log(data); })();七、本章小結知識點說明async聲明異步函數返回 Promiseawait等待 Promise 解決只能在 async 函數中使用錯誤處理使用try/catch或.catch()處理異步錯誤并行執行使用Promise.all同時執行多個獨立的異步操作順序執行使用await依次執行有依賴關系的異步操作頂層 awaitES 模塊中支持CommonJS 中需包裹在 async 函數中提示async/await 是現代 Node.js 異步編程的推薦方式。它讓異步代碼看起來像同步代碼大大提高了代碼的可讀性和可維護性。但要記住await會暫停函數執行在循環中使用時要考慮性能影響無關的操作應該用Promise.all并行執行。