第 10 课:Promise 基础 —— 什么是 Promise?

4 阅读2分钟

太棒了!👏 你已经走过了回调函数的“原始时代”,现在我们正式进入现代 JavaScript 异步编程的核心 —— Promise


📌 核心知识点
Promise 是一个表示异步操作“未来结果”的对象,它有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)。


🌱 从生活例子理解 Promise

想象你在点外卖:

  • 下单那一刻,你就得到了一个 承诺(Promise) :“你的餐正在路上,稍后会送达。”
  • 这个承诺可能:
    • ✅ 成功(fulfilled):餐送到了
    • ❌ 失败(rejected):骑手摔了,餐没了
    • ⏳ 中间状态(pending):还在等

👉 在代码里,Promise 就是用来描述这种“未来才会知道结果”的操作。


🔧 创建一个 Promise

语法:

const myPromise = new Promise((resolve, reject) => {
  // 异步操作写在这里
  // 成功用 resolve(值)
  // 失败用 reject(错误)
});

💡 示例:模拟读取用户信息

function fetchUser() {
  return new Promise((resolve, reject) => {
    // 模拟网络延迟
    setTimeout(() => {
      const success = true; // 模拟是否成功

      if (success) {
        resolve({ id: 1, name: "Alice" }); // 成功返回数据
      } else {
        reject(new Error("无法加载用户")); // 失败抛出错误
      }
    }, 1000);
  });
}

▶️ 使用 Promise:.then().catch()

fetchUser()
  .then(user => {
    console.log('✅ 用户加载成功:', user);
  })
  .catch(err => {
    console.error('❌ 出错了:', err.message);
  });

📌 执行流程:

  1. fetchUser() 开始执行(内部是异步)
  2. 1秒后,如果成功 → 调用 .then
  3. 如果失败 → 跳到 .catch

✅ 输出(成功时):

✅ 用户加载成功: { id: 1, name: 'Alice' }

🔄 Promise 的三种状态

状态含义特点
pending等待中初始状态,既没成功也没失败
fulfilled已成功调用了 resolve(value)
rejected已失败调用了 reject(error)

⚠️ 一旦状态改变(从 pending → fulfilled 或 rejected),就不可逆


✅ 链式调用:.then() 返回新 Promise

这是 Promise 最强大的地方:可以链式处理多个异步任务!

fetchUser()
  .then(user => {
    console.log('第一步:拿到用户', user.name);
    return user;
  })
  .then(user => {
    console.log('第二步:获取他的文章列表');
    return ['文章1', '文章2']; // 模拟返回数据
  })
  .then(posts => {
    console.log('第三步:显示文章', posts);
  })
  .catch(err => {
    console.error('整个过程中出错:', err.message);
  });

输出:

第一步:拿到用户 Alice
第二步:获取他的文章列表
第三步:显示文章 [ '文章1', '文章2' ]

🎉 没有嵌套!逻辑清晰!这才是我们要的代码!


🛠️ 实际应用:用 Promise 包装 fs.readFile

Node.js 内置方法大多是回调风格,我们可以手动包装成 Promise:

const fs = require('fs');

function readFile(filename) {
  return new Promise((resolve, reject) => {
    fs.readFile(filename, 'utf8', (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
  });
}

// 使用方式
readFile('hello.txt')
  .then(content => console.log(content))
  .catch(err => console.error('读取失败:', err));

💡 提示:Node.js 提供了 util.promisify() 可以自动转换,后面我们会讲。


本课小结一句话

Promise 是对异步操作的“承诺”,通过 .then() 处理成功,.catch() 处理失败,避免回调地狱,让异步代码更清晰可控。


📬 下一课预告:
第 11 课:async/await —— 让异步代码看起来像同步一样简单!

我们将学习最现代、最推荐的写法,让你的代码像“读小说”一样自然流畅。