Skip to content

十二、async / await(异步终极方案)

async/await 是 ES8 引入的异步编程语法糖,它基于 Promise,使异步代码看起来更像同步代码,更加清晰易读。

什么是 async / await?

  • async:用于声明一个函数是异步的,返回一个 Promise
  • await:用于等待一个 Promise 完成,只能在 async 函数中使用

基础用法

基本语法

javascript
// 定义异步函数
async function fetchData() {
  // 等待 Promise 完成
  const result = await new Promise(resolve => {
    setTimeout(() => resolve('数据'), 1000);
  });
  console.log(result); // 数据
  return result;
}

// 调用异步函数
fetchData().then(data => {
  console.log('异步函数返回:', data); // 异步函数返回: 数据
});

与 Promise 结合

javascript
// 模拟 API 请求
function fetchUser() {
  return new Promise(resolve => {
    setTimeout(() => resolve({ id: 1, name: 'John' }), 1000);
  });
}

function fetchPosts(userId) {
  return new Promise(resolve => {
    setTimeout(() => resolve([
      { id: 1, title: 'Post 1' },
      { id: 2, title: 'Post 2' }
    ]), 1000);
  });
}

// 使用 async/await
async function getUserPosts() {
  try {
    // 等待获取用户
    const user = await fetchUser();
    console.log('用户:', user);
    
    // 等待获取帖子
    const posts = await fetchPosts(user.id);
    console.log('帖子:', posts);
    
    return { user, posts };
  } catch (error) {
    console.error('错误:', error);
  }
}

getUserPosts().then(result => {
  console.log('结果:', result);
});

错误处理

try/catch

javascript
async function fetchData() {
  try {
    const result = await new Promise((resolve, reject) => {
      setTimeout(() => reject('出错了'), 1000);
    });
    console.log(result);
  } catch (error) {
    console.error('捕获到错误:', error); // 捕获到错误: 出错了
  }
}

fetchData();

外部捕获

javascript
async function fetchData() {
  const result = await new Promise((resolve, reject) => {
    setTimeout(() => reject('出错了'), 1000);
  });
  return result;
}

fetchData()
  .then(result => console.log(result))
  .catch(error => console.error('捕获到错误:', error)); // 捕获到错误: 出错了

结合 Promise 使用

并发请求

javascript
async function fetchAllData() {
  // 同时发起多个请求
  const [user, posts, comments] = await Promise.all([
    fetchUser(),
    fetchPosts(1),
    fetchComments(1)
  ]);
  
  console.log('用户:', user);
  console.log('帖子:', posts);
  console.log('评论:', comments);
  
  return { user, posts, comments };
}

fetchAllData();

处理多个异步操作

javascript
async function processData() {
  // 顺序执行
  const data1 = await fetchData1();
  const data2 = await fetchData2(data1);
  const data3 = await fetchData3(data2);
  return data3;
}

processData().then(result => {
  console.log('最终结果:', result);
});

实战:模拟异步获取数据

javascript
// 模拟 API 请求
function fetchData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`Fetching from ${url}`);
      resolve(`Data from ${url}`);
    }, Math.random() * 1000);
  });
}

// 使用 async/await
async function getData() {
  try {
    console.log('开始获取数据...');
    
    // 并发请求
    const [users, posts, comments] = await Promise.all([
      fetchData('https://api.example.com/users'),
      fetchData('https://api.example.com/posts'),
      fetchData('https://api.example.com/comments')
    ]);
    
    console.log('获取数据完成');
    console.log('用户数据:', users);
    console.log('帖子数据:', posts);
    console.log('评论数据:', comments);
    
    return { users, posts, comments };
  } catch (error) {
    console.error('获取数据失败:', error);
  }
}

getData().then(result => {
  console.log('最终结果:', result);
});

async/await 的优势

  1. 代码简洁:使异步代码看起来更像同步代码
  2. 可读性高:逻辑流程清晰明了
  3. 错误处理简单:可以使用 try/catch 进行错误处理
  4. 易于调试:调试时可以设置断点,一步一步执行
  5. 与 Promise 兼容:完全基于 Promise,可以与 Promise 无缝配合

异步编程发展历程

  1. 回调函数:最早的异步处理方式,容易形成回调地狱
  2. Promise:解决了回调地狱问题,提供了链式调用
  3. async/await:基于 Promise,使代码更加简洁易读

对比

javascript
// 回调地狱
function callbackHell() {
  step1(function(result1) {
    step2(result1, function(result2) {
      step3(result2, function(result3) {
        console.log(result3);
      });
    });
  });
}

// Promise
function promiseChain() {
  step1()
    .then(result1 => step2(result1))
    .then(result2 => step3(result2))
    .then(result3 => console.log(result3))
    .catch(error => console.error(error));
}

// async/await
async function asyncAwait() {
  try {
    const result1 = await step1();
    const result2 = await step2(result1);
    const result3 = await step3(result2);
    console.log(result3);
  } catch (error) {
    console.error(error);
  }
}

通过本章节的学习,你已经掌握了 async/await 的基本用法和优势。async/await 是目前最流行的异步编程方式,它使异步代码更加简洁易读,提高了开发效率。

© 2026 编程马·菜鸟教程 版权所有