当然可以!async 和 await 是 JavaScript 中用于简化 异步编程 的语法糖,它们构建在 Promise 之上,能让异步代码写起来像同步代码一样清晰


✨ 一句话理解

  • async 用于声明一个异步函数,这个函数总是返回一个 Promise
  • await 用于等待一个 Promise 的结果,只能在 async 函数内部使用。

🔧 1. async 函数

async function foo() {
  return 42;
}

上面的 foo() 实际上等价于:

function foo() {
  return Promise.resolve(42);
}

你可以这样调用它:

foo().then(value => {
  console.log(value); // 输出 42
});

🕓 2. await 用法

await 可以暂停 async 函数的执行,直到 Promise 执行完成,返回其结果。

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function example() {
  console.log('开始');
  await delay(1000); // 等待 1 秒
  console.log('1 秒后继续');
}

⚡ 示例:请求数据的对比

✅ 使用 async/await(简洁清晰)

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('发生错误:', error);
  }
}

❌ 等价的 Promise 写法(回调嵌套多)

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('发生错误:', error);
  });

📌 3. async/await 的规则总结

规则说明
只能在 async 函数内部使用 await否则会报错
async 函数总是返回一个 Promise即使你返回的是普通值
await 等待的是一个 Promise如果不是 Promise,也会自动转换成已完成的 Promise
可以用 try/catch 捕获异常更易读

🔁 4. 多个异步串行和并行的对比

串行执行(等待上一个执行完)

await doTask1();  // 等待执行完
await doTask2();  // 等待执行完

并行执行(同时发起)

const [res1, res2] = await Promise.all([doTask1(), doTask2()]);

❗ 错误处理建议

用 try/catch 包住 await,能更优雅地处理错误:

async function safeCall() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (e) {
    console.error('请求失败:', e);
  }
}

🧠 总结记忆口诀

async 返回 Promise,await 等待 Promise。
能让异步写法像同步,看起来更清晰。
只能在 async 函数中用 await,不要在全局乱用。

🚀 拓展阅读

  • Promise.all / Promise.race 与 await 配合
  • 顶层 await(ES2022 支持)
  • async 递归、并发控制等高级用法

好的!以下是一个完整的 async/await 异步请求实战案例,涵盖:

  • 异步请求接口数据
  • 错误处理(try/catch)
  • 并发请求(Promise.all
  • 请求失败自动重试机制(进阶)

✅ 场景说明

假设我们要请求一个用户 API,比如:

  • https://jsonplaceholder.typicode.com/users/1
  • https://jsonplaceholder.typicode.com/users/2
  • 等等…

我们希望:

  1. 支持并发请求多个用户数据
  2. 如果有请求失败,能够优雅地处理
  3. 支持失败自动重试(可选)

🧩 完整代码示例(浏览器可直接运行)

// 一个延时函数(模拟网络延迟)
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// 获取单个用户信息(带错误处理)
async function fetchUser(userId) {
  const url = `https://jsonplaceholder.typicode.com/users/${userId}`;
  try {
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error(`用户 ${userId} 请求失败,状态码: ${response.status}`);
    }

    const data = await response.json();
    console.log(`✅ 用户 ${userId} 数据:`, data);
    return data;
  } catch (error) {
    console.error(`❌ 获取用户 ${userId} 失败:`, error.message);
    return null;
  }
}

// 批量获取多个用户信息(并发 + 错误处理)
async function fetchMultipleUsers(userIds) {
  const promises = userIds.map(id => fetchUser(id));
  const results = await Promise.all(promises); // 并发请求

  const successful = results.filter(user => user !== null);
  console.log(`🎉 成功获取了 ${successful.length} 个用户数据`);
}

// 可选进阶:支持失败自动重试(最多重试 3 次)
async function fetchWithRetry(fn, retries = 3, delayMs = 1000) {
  for (let i = 0; i <= retries; i++) {
    try {
      return await fn();
    } catch (err) {
      console.warn(`⚠️ 第 ${i + 1} 次尝试失败: ${err.message}`);
      if (i < retries) {
        await delay(delayMs);
      } else {
        throw err;
      }
    }
  }
}

// 使用示例
(async () => {
  const userIds = [1, 2, 3, 999]; // 999 是故意让一个失败

  console.log('📡 开始请求多个用户信息...');
  await fetchMultipleUsers(userIds);
})();

🧠 你学到的核心知识点:

技术点示例
async/await用于异步操作流程化
try/catch捕获请求异常
Promise.all多个异步任务并发处理
自定义封装 fetchWithRetry异常重试机制