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

如何在Promise.all()中使用布尔值实现状态就绪等待逻辑

实现可等待多状态就绪的Promise方法

我来帮你搞定这个需求!你原来的写法有个关键问题:Promise.all([statusReady, jobsReady]) 传入的是普通布尔值,Promise会直接把它们包装成已完成的Promise——不管值是true还是false,都会立即resolve,完全起不到等待状态变为true的作用。

要实现当所有变量为true时立即resolve,否则等待状态变更的效果,我们需要给状态变量绑定监听逻辑,用Promise来等待它们的状态变化。下面是两种实用的实现方案:

方案一:手动更新状态 + Promise缓存

这种方式通过专门的更新方法来修改状态,同时缓存就绪Promise,避免重复创建:

class YourClass {
  constructor() {
    this.statusReady = false;
    this.jobsReady = false;
    // 缓存就绪Promise,多次调用ready()返回同一个实例
    this._readyPromise = null;
    // 保存Promise的resolve函数,状态就绪时触发
    this._resolveReady = null;
  }

  ready() {
    // 如果已有等待中的Promise,直接返回它
    if (this._readyPromise) {
      return this._readyPromise;
    }

    // 检查当前是否已经全部就绪,是的话直接返回已resolve的Promise
    if (this.statusReady && this.jobsReady) {
      return Promise.resolve();
    }

    // 创建新的Promise,把resolve函数存起来
    this._readyPromise = new Promise((resolve) => {
      this._resolveReady = resolve;
    });

    return this._readyPromise;
  }

  // 用来更新状态的方法,每次更新后检查是否全部就绪
  updateStatus(key, value) {
    this[key] = value;
    // 两个状态都为true时,触发resolve并清理缓存
    if (this.statusReady && this.jobsReady) {
      this._resolveReady?.();
      this._readyPromise = null;
      this._resolveReady = null;
    }
  }
}

使用示例:

const instance = new YourClass();

// 模拟异步状态变更
setTimeout(() => {
  instance.updateStatus('statusReady', true);
}, 1000);

setTimeout(() => {
  instance.updateStatus('jobsReady', true);
}, 2000);

// 等待就绪后执行操作
instance.ready().then(() => {
  console.log('所有状态已就绪!可以开始干活了🥳');
});

方案二:用getter/setter自动监听状态变化

如果不想手动调用updateStatus,可以用getter和setter来自动监听状态变更,赋值时自动检查就绪条件:

class YourClass {
  constructor() {
    this._statusReady = false;
    this._jobsReady = false;
    this._readyPromise = null;
    this._resolveReady = null;
  }

  get statusReady() {
    return this._statusReady;
  }

  set statusReady(value) {
    this._statusReady = value;
    this._checkIfReady();
  }

  get jobsReady() {
    return this._jobsReady;
  }

  set jobsReady(value) {
    this._jobsReady = value;
    this._checkIfReady();
  }

  ready() {
    if (this._readyPromise) {
      return this._readyPromise;
    }

    if (this.statusReady && this.jobsReady) {
      return Promise.resolve();
    }

    this._readyPromise = new Promise((resolve) => {
      this._resolveReady = resolve;
    });

    return this._readyPromise;
  }

  // 私有方法:检查是否所有状态都就绪
  _checkIfReady() {
    if (this.statusReady && this.jobsReady) {
      this._resolveReady?.();
      this._readyPromise = null;
      this._resolveReady = null;
    }
  }
}

使用示例:

const instance = new YourClass();

// 直接赋值状态即可,无需手动调用更新方法
setTimeout(() => {
  instance.statusReady = true;
}, 1000);

setTimeout(() => {
  instance.jobsReady = true;
}, 2000);

instance.ready().then(() => {
  console.log('所有状态已就绪!可以开始干活了🥳');
});

核心逻辑说明

  1. Promise缓存:避免每次调用ready()都创建新的Promise,确保多次调用返回的是同一个等待实例,不会重复监听。
  2. 保存resolve函数:在Promise初始化时把resolve函数存下来,当所有状态都变为true时,手动调用它来完成Promise。
  3. 状态变更检查:每次状态更新后,立即检查是否满足所有就绪条件,满足则触发resolve并清理缓存,让下次调用ready()可以重新判断当前状态。

这样就能完美实现你想要的效果:如果调用ready()时两个状态已经是true,Promise会立即resolve;如果有一个或两个是false,就会等待它们变为true后再resolve。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:22:01