如何让异步调用代码更清晰易读

8次阅读

如何让异步调用代码更清晰易读

本文介绍如何通过合理使用 `async/await` 替代 `.then()` 链式调用,提升异步代码的可读性与可维护性,并给出符合最佳实践的重构示例。

javaScript 异步编程中,.then().catch() 链虽然功能完备,但嵌套过深或逻辑复杂时容易导致“回调地狱”式的可读性下降。而 async/await 语法以同步风格书写异步逻辑,显著增强代码的线性表达力和语义清晰度。

你当前的写法:

const apiCall = async() => {   const response = await axios.get("URL");   return response; }  apiCall().then(res => {   console.log(res.data); });

虽已使用 async/await 封装请求,但在调用端仍依赖 .then(),未能充分发挥其优势。更推荐的方式是全程统一使用 async/await,包括调用层:

✅ 推荐重构方案(简洁、语义明确、错误可捕获):

const apiCall = async () => {   try {     const { data } = await axios.get("URL");     return data; // 直接解构并返回业务数据,避免上层重复访问 .data   } catch (error) {     console.error("API 请求失败:", error.message);     throw error; // 保留错误,便于上层处理(如重试、兜底 UI)   } };  const fetchData = async () => {   try {     const data = await apiCall();     console.log(data);     return data;   } catch (error) {     // 可在此处添加特定业务错误处理逻辑     throw error;   } };  // 正确调用方式(必须在 async 上下文中) fetchData().catch(console.error);  // 或在顶层模块中使用 IIFE(适用于非模块环境或 script 标签) (async () => {   try {     const result = await fetchData();     console.log("获取成功:", result);   } catch (err) {     console.warn("最终未捕获的异常:", err);   } })();

⚠️ 注意事项:

  • await 只能在 async 函数内部使用,因此 console.log(fetchData()) ❌ 是错误的——它会打印一个 promise 对象,而非实际数据;
  • 始终包裹 await 调用在 try/catch 中,避免未捕获的 Promise rejection 导致静默失败;
  • 接口函数(如 apiCall)应聚焦职责:封装请求 + 统一错误处理 + 返回干净的数据结构(如直接返回 data),降低消费者耦合度;
  • 若需复用底层 Promise(如并发请求),可保留 axios.get(…) 的原始 Promise 返回,但此时函数不应声明为 async,否则会多一层不必要的 Promise 包装。

总结:可读性提升的关键不在于“是否用了 await”,而在于统一范式、职责分离、错误显式化、数据标准化。从 .then() 迁移至 async/await 不仅是语法糖替换,更是异步流程设计思维的升级。

text=ZqhQzanResources