🎯 第 11 课:async/await —— 让异步代码像同步一样简单

2 阅读2分钟

太棒了!👏 你已经掌握了 Promise,现在我们进入 异步编程的终极形态 —— async/await


📌 核心知识点
async 函数是 Promise 的语法糖,用 await 可以“暂停”函数执行直到 Promise 完成,让异步代码看起来像同步,更易读、易写。


✨ 为什么需要 async/await?

还记得这个吗?

fetchUser()
  .then(user => {
    return fetchPosts(user.id);
  })
  .then(posts => {
    return fetchPostContent(posts[0]);
  })
  .then(content => {
    console.log(content);
  })
  .catch(err => {
    console.error(err);
  });

✅ 虽然解决了回调地狱,但还是有点“绕”。

我们真正想要的是:

“先拿用户 → 再拿文章 → 再拿内容”,一行接一行,像普通代码那样。

👉 这就是 async/await 的使命!


🔧 基本语法

1. 在函数前加 async

async function myFunction() {
  // 这个函数一定会返回一个 Promise
}

2. 在 Promise 前用 await

const result = await someAsyncOperation();
// 等待完成后再继续下一行

💡 实战对比:Promise vs async/await

假设我们有三个异步函数(已返回 Promise):

function fetchUser() {
  return Promise.resolve({ id: 1, name: "Alice" });
}

function fetchPosts(userId) {
  return Promise.resolve(["《Node.js 入门》", "《异步编程详解》"]);
}

function fetchPostContent(title) {
  return Promise.resolve(`内容:欢迎阅读 ${title}`);
}

❌ 使用 .then() 风格

fetchUser()
  .then(user => fetchPosts(user.id))
  .then(posts => fetchPostContent(posts[0]))
  .then(content => console.log(content))
  .catch(err => console.error(err));

✅ 使用 async/await 风格

async function showFirstPost() {
  try {
    const user = await fetchUser();
    const posts = await fetchPosts(user.id);
    const content = await fetchPostContent(posts[0]);

    console.log(content);
  } catch (err) {
    console.error(err);
  }
}

// 调用它
showFirstPost();

🎯 输出相同:

内容:欢迎阅读 《Node.js 入门》

但代码更清晰、逻辑更直白!


⚠️ 注意事项

1. await 只能在 async 函数中使用

❌ 错误:

// 顶层不能直接用 await(除非在模块顶级或 REPL)
const user = await fetchUser(); // SyntaxError!

✅ 正确:

async function main() {
  const user = await fetchUser();
  console.log(user);
}
main();

2. 用 try...catch 捕获错误

因为 await 会让代码“看起来像同步”,所以我们也用同步的方式处理异常:

try {
  const user = await fetchUser();
  console.log('成功:', user);
} catch (err) {
  console.error('失败:', err.message);
}

🛠️ 实际应用:用 async/await 重写文件读取

const { promisify } = require('util');
const fs = require('fs');

// 把回调函数转成 Promise 版本
const readFile = promisify(fs.readFile);

async function readMyFile() {
  try {
    const content = await readFile('hello.txt', 'utf8');
    console.log('文件内容:', content);
  } catch (err) {
    console.error('读取失败:', err);
  }
}

readMyFile();

🎉 简洁!直观!现代 Node.js 开发的标准写法!


✅ 小结一句话:

async/await 是基于 Promise 的语法糖,让你用“同步风格”写异步代码,配合 try/catch 处理错误,大幅提升可读性和维护性。


📬 下一课预告:
第 12 课:使用内置 http 模块创建 Web 服务器 —— 手把手教你搭建第一个网站!

我们将用今天学的知识,结合 http 模块,做一个能被浏览器访问的服务器。