人人都会AI编程

三种状态、状态不可逆特性

更新时间:2026-07-11

Promise 对象代表一个异步操作的最终完成或失败,以及其结果值。它的核心在于一个简单的状态模型——理解这个模型,就理解了 Promise 的行为规则。

三种状态

一个 Promise 实例在任意时刻必然处于以下三种状态之一:

  • Pending(待定):初始状态,异步操作尚未完成,既没有成功也没有失败。
  • Fulfilled(已完成):异步操作成功完成,Promise 拥有了一个不可变的结果值。
  • Rejected(已拒绝):异步操作失败,Promise 拥有了一个不可变的失败原因(通常是一个 Error 对象)。

可以用一个日常比喻来理解:Promise 像是一张外卖订单。刚下单时是“待定”,厨师开始做;当快递员取到餐点,“已完成”(你可以拿结果值——餐点);如果餐馆打来电话说卖完了,“已拒绝”(你会得到一个理由——卖完了)。

// 创建后处于 pending 状态
const promise = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    const success = Math.random() > 0.5;
    if (success) {
      resolve('数据');      // 转为 fulfilled
    } else {
      reject(new Error('网络错误')); // 转为 rejected
    }
  }, 1000);
});

console.log(promise); // Promise {<pending>}

状态不可逆:一旦确定,永远不会改变

这是 Promise 最基本、最重要的可靠性保证:Promise 的状态只能从 pending 变为 fulfilled 或 rejected,一旦变更,就永久凝固,不能再变回 pending,也不能切换到另一个终态。 这个结果值和状态会被一直保留,即使你在状态确定之后很久才去添加 .then().catch(),依然能拿到当初的结果。

const promise = new Promise((resolve, reject) => {
  resolve('第一次');  // promise 变为 fulfilled,值为 '第一次'
  reject(new Error('第二次')); // 这行代码无效,被完全忽略
  resolve('第三次');  // 同样无效
});

promise.then(
  value => console.log(value),       // 输出 '第一次'
  error => console.log(error)        // 不会执行
);

上面的代码中,当 resolve('第一次') 执行后,Promise 已经从 pending 转变为了 fulfilled,后续任何 rejectresolve 调用都会被引擎静默忽略。这种“一次性”特性避免了回调地狱中常见的多次调用、提前或延迟调用导致的状态混乱问题。

实际开发中的价值

  • 你可以安全地多次订阅同一个 Promise,它不会多次触发异步操作,也不会因为时间差而丢失结果。
  • 无论你在路由跳转、组件卸载、或超时取消时如何操作,已经 settled(确定状态)的 Promise 不会受到干扰,避免了“竞态”中的状态污染。
  • 这种确定性使得 Promise 可以放心地作为异步结果的标准化容器,在组合、链式调用、并发控制中保持行为一致。

与“取消”的区别

需注意,Promise 没有内置的取消机制。一旦异步操作启动,Promise 的状态终究会变为 fulfilled 或 rejected,你不能中途将其重置为 pending。如果要实现“取消”效果,常见的做法是结合一个封装好的标志位或使用第三方库(如 Axios 的 CancelToken),让异步操作的完成回调根据标志判断是否忽略结果,而不是去改变 Promise 的状态本身。

小结

Promise 的三种状态和不可逆特性共同构成了它作为异步基础的可靠性:一旦你得到一个 Promise,你就可以信赖它的结果永远不会变。这一简单的保证,让复杂的异步流程组合成为可能,也为 async/await 提供了坚实的底层基础。理解这一点,是写出正确异步代码的起点。