Promise

Promise 是表示未来结果的对象。

#type / concept #status / growing #resource / javascript #resource / ecmascript

[!info] related notes

Promise

Promise 是为了解决“异步结果未来才会到”这个问题的。

你可以先记住一句:

Promise 是一个表示“未来结果”的对象。

为什么需要 Promise

最早很多异步代码这样写:

setTimeout(() => {
  console.log("step1");
  setTimeout(() => {
    console.log("step2");
    setTimeout(() => {
      console.log("step3");
    }, 1000);
  }, 1000);
}, 1000);

这会形成层层嵌套,难读难维护。

Promise 的核心价值是:

  • 把“未来会完成的结果”包装起来
  • 让异步流程变得可链式组织
  • 让成功 / 失败处理更统一

Promise 的三种状态

一个 Promise 有三种状态:

1. pending

进行中。

2. fulfilled

已成功。

3. rejected

已失败。

并且状态一旦从 pending 变成成功或失败,就不会再变。

最基础的 Promise 写法

const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("done");
  }, 1000);
});

这里:

  • new Promise(...) 创建了一个 Promise
  • 传进去的函数会立即执行
  • resolve("done") 表示成功
  • reject(err) 表示失败

then

p.then(onFulfilled, onRejected);

当 Promise 成功时,then 里的回调会执行。

[!info] 注意 then 中的参数应该是函数,非函数会被忽略 3. Promise then callbacks | BFE.dev - 前端刷题,准备前端面试拿到心仪的Offer。

一个完整例子

const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("success");
  }, 1000);
});

p.then((value) => {
  console.log(value);
});

1 秒后输出:

success

Promise 不是“把代码变同步”

这一点很重要。

很多人刚学 Promise,会误以为:

有了 Promise,我就能马上拿到结果了。

不是。

比如:

const p = new Promise((resolve) => {
  setTimeout(() => {
    resolve(123);
  }, 1000);
});

console.log(p);

这里立刻打印出来的不是 123,而是一个还没完成或已完成的 Promise 对象。

说明 Promise 不是同步结果,而是结果的占位符

then 返回新的 Promise

这是 Promise 链式调用的根本原因。

Promise.resolve(1)
  .then((value) => {
    console.log(value);
    return value + 1;
  })
  .then((value) => {
    console.log(value);
    return value + 1;
  })
  .then((value) => {
    console.log(value);
  });

输出:

1
2
3

每个 then 都会返回一个新的 Promise,所以可以继续接下去。

catch

Promise.reject("error")
  .catch((err) => {
    console.log(err);
  });

用于处理失败。

finally

Promise.resolve("ok")
  .finally(() => {
    console.log("finally");
  });

无论成功失败都会执行,适合做收尾动作。

Promise 回调为什么常常比 setTimeout

因为 .then(...) 的回调属于微任务,而 setTimeout 属于宏任务

setTimeout(() => console.log("timeout"), 0);

Promise.resolve().then(() => {
  console.log("promise");
});

输出:

promise
timeout

Promise 解析过程(Promise Resolution Procedure)

这是 Promise 最容易被忽略的深层机制:resolve 一个 Promise / thenable 时到底发生了什么?

核心规则:状态可以跟随,身份不会复用

resolve(x) 中的 x 本身是一个 Promise 或 thenable(有 .then 方法的对象)时,新 Promise 不会把 x 当普通值包一层,而是采用它的状态和值

但它们仍然是不同的对象

Promise.resolve(x) 的特殊行为

const p1 = Promise.resolve(1)
const p3 = Promise.resolve(p1)

p1 === p3  // true

如果参数已经是 Promise,Promise.resolve 直接返回它本身。 这是唯一会”复用同一个对象”的情况。

对比:

const p1 = Promise.resolve(1)
const p2 = new Promise((resolve) => resolve(p1))

p1 === p2  // false

new Promise 一定会创建新对象。resolve(p1) 只会让 p2 跟随 p1 的状态,但 p2 是独立的新对象。

then() 永远返回新 Promise

const p1 = Promise.resolve(1)
const p4 = p1.then(() => p1)

p1 === p4  // false

即使回调返回 p1 本身,then 返回的 p4 也是新的 Promise 对象。p4 的状态和值会跟随 p1,但身份不同。

完整身份判断示例

const p1 = Promise.resolve(1)
const p2 = new Promise((resolve) => resolve(p1))
const p3 = Promise.resolve(p1)
const p4 = p2.then(() => new Promise((resolve) => resolve(p3)))
const p5 = p4.then(() => p4)

console.log(p1 == p2)  // false  new Promise 总是新建
console.log(p1 == p3)  // true   Promise.resolve(已有Promise) 直接返回原 Promise
console.log(p3 == p4)  // false  then 总是返回新 Promise
console.log(p4 == p5)  // false  then 总是返回新 Promise

解析规则总结

情况是否新建对象状态如何
new Promise(resolve => resolve(x)),x 是普通值新建直接 fulfilled
new Promise(resolve => resolve(p)),p 是 Promise新建跟随 p
Promise.resolve(p),p 是 Promise不新建,返回 p 本身p 的状态
Promise.resolve(x),x 是普通值新建fulfilled
p.then(fn),fn 返回普通值新建fulfilled,值为返回值
p.then(fn),fn 返回 Promise新建跟随返回的 Promise
p.then(fn),fn 返回 thenable新建跟随 thenable(调用其 .then

thenable 同化(thenable assimilation)

如果 resolve(x) 中的 x 是一个有 .then 方法的对象(但不是真正的 Promise),引擎会调用 x.then 来获取最终状态:

const thenable = {
  then(resolve) {
    resolve(42);
  }
};

const p = Promise.resolve(thenable);
p.then(v => console.log(v));  // 42

这就是 Promise Resolution Procedure 的核心:遇到 thenable 就展开,直到拿到非 thenable 的值。

Promise 链的本质

你可以把它理解成:

前一个异步步骤完成后,把结果交给下一个步骤。

例如:

function step1() {
  return Promise.resolve(1);
}

function step2(value) {
  return Promise.resolve(value + 1);
}

function step3(value) {
  return Promise.resolve(value + 1);
}

step1()
  .then(step2)
  .then(step3)
  .then((result) => {
    console.log(result); // 3
  });

和其他笔记怎么分工

创建于 2026/3/15 更新于 2026/5/27