极简三分钟ES6 - ES8中async,await

237 阅读2分钟

基础概念:快递员与包裹

想象我们要接收两个快递

  • 传统回调/Promise:反复查物流(.then()嵌套),流程繁琐
  • async/await:告诉快递员(async函数)“到了叫我”(await),那我们就能专心做其他事
// 传统 Promise 链 
fetchData()
  .then(data => process(data))
  .then(result => console.log(result)) 
  .catch(err => console.error(err)); 
 
// async/await 写法 
async function handleData() {
  try {
    const data = await fetchData(); // 等包裹送达 
    const result = await process(data); // 拆包裹后加工 
    console.log(result); 
  } catch (err) {
    console.error(err);  // 包裹异常统一处理 
  }
}

使用规则详解

async 标记异步函数

函数前加 async自动返回 Promise 对象

async function getNum() { return 42; }
getNum().then(num => console.log(num));  // 输出 42 

await 暂停等待结果

在 async 函数内使用,暂停代码执行直到右侧表达式完成

async function demo() {
  console.log(" 开始等待");
  await new Promise(resolve => setTimeout(resolve, 2000)); // 等 2 秒 
  console.log(" 等待结束");
}

错误处理:try/catch 替代 .catch()

用同步语法捕获异步错误

async function fetchUser() {
  try {
    const user = await fetch("/api/user");
    console.log(user); 
  } catch (error) {
    console.error(" 请求失败:", error);
  }
}

解决四大痛点

痛点场景async/await 方案传统方案问题
回调地狱扁平化代码结构多重嵌套难维护
Promise 链中断try/catch 直接捕获错误需每个 .then() 后接 .catch()
同步取值困难const res = await asyncTask()需在 .then() 内操作
条件分支处理复杂直接写 if/else 逻辑链式调用分支混乱

一些常见的使用场景

按顺序调用多个接口

async function initPage() {
  const user = await getUserInfo();      // 等用户数据 
  const orders = await getOrders(user.id);  // 用用户ID查订单 
  renderPage(user, orders);              // 渲染页面 
}

循环中的异步操作

async function batchDownload(urls) {
  for (const url of urls) {
    const data = await download(url); // 等上一个下载完 
    saveToDisk(data);
  }
}

并行优化:Promise.all 搭配使用

async function loadAll() {
  const [news, ads] = await Promise.all([ 
    fetchNews(),
    fetchAds()
  ]); // 同时发请求,等全部返回 
  return { news, ads };
}

牢记

async 造个快递员,await 坐等不焦虑,错误抓进 try/catch,异步同步两相宜。”