You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Promise构造函数内局部变量如何维持状态?

关于Promise构造函数局部变量状态维持与闭包的疑问解答

首先纠正一个对闭包的误解:闭包不是只有「外部函数返回内部函数」这一种形式。闭包的核心是内部函数能访问外部函数作用域里的变量,哪怕外部函数已经执行完毕——不管这个内部函数是被返回出去,还是挂载到对象上,或是被传递给其他函数,只要它还存在,就会形成闭包。

拿Promise的简易实现来说,看这段核心代码:

function MyPromise(executor) {
  // 构造函数内的局部变量,用来存状态和值
  let state = 'pending';
  let value = null;
  const callbacks = [];

  // 内部定义的resolve函数,闭包了state、value、callbacks
  function resolve(val) {
    if (state !== 'pending') return;
    state = 'fulfilled';
    value = val;
    callbacks.forEach(cb => cb.onFulfilled(val));
  }

  // 内部定义的reject函数,同样闭包了局部变量
  function reject(reason) {
    if (state !== 'pending') return;
    state = 'rejected';
    value = reason;
    callbacks.forEach(cb => cb.onRejected(reason));
  }

  // 挂载到实例上的then方法,也闭包了state、value、callbacks
  this.then = function(onFulfilled, onRejected) {
    return new MyPromise((resolveNext, rejectNext) => {
      if (state === 'fulfilled') {
        // 直接使用构造函数里的value
        const res = onFulfilled(value);
        resolveNext(res);
      } else if (state === 'rejected') {
        // 直接使用构造函数里的value(reason)
        const res = onRejected(value);
        resolveNext(res);
      } else {
        // 往构造函数里的callbacks数组加回调
        callbacks.push({
          onFulfilled: (val) => {
            const res = onFulfilled(val);
            resolveNext(res);
          },
          onRejected: (reason) => {
            const res = onRejected(reason);
            resolveNext(res);
          }
        });
      }
    });
  };

  executor(resolve, reject);
}

当你创建const promiseA = new MyPromise(...)时,MyPromise构造函数会完整执行一次:

  1. 此时创建了state、value、callbacks这几个局部变量;
  2. 定义了resolve、reject函数,以及挂载到this(也就是promiseA实例)上的then方法;
  3. 把resolve和reject传给executor函数执行。

构造函数执行完毕后,这些局部变量并没有被销毁——因为resolve、reject、promiseA.then这三个函数都引用了它们,形成了闭包。

比如:

  • 当executor里调用resolve(xxx)时,执行的是构造函数里定义的那个resolve,它修改的是当初构造函数执行时创建的state和value;
  • 当你调用promiseA.then(...)时,执行的是挂载到实例上的then方法,它直接读取的是当初构造函数里的state和value,或者往callbacks数组里加回调——这些变量都是第一次构造函数执行时创建的,不会重新生成。

所以哪怕每次调用then都会创建新的Promise实例,原Promise实例的状态变量依然会被闭包保留,不会被回收,自然能维持住状态。

内容的提问来源于stack exchange,提问作者lch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 17:55:09