如何在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('所有状态已就绪!可以开始干活了🥳'); });
核心逻辑说明
- Promise缓存:避免每次调用
ready()都创建新的Promise,确保多次调用返回的是同一个等待实例,不会重复监听。 - 保存resolve函数:在Promise初始化时把resolve函数存下来,当所有状态都变为
true时,手动调用它来完成Promise。 - 状态变更检查:每次状态更新后,立即检查是否满足所有就绪条件,满足则触发resolve并清理缓存,让下次调用
ready()可以重新判断当前状态。
这样就能完美实现你想要的效果:如果调用ready()时两个状态已经是true,Promise会立即resolve;如果有一个或两个是false,就会等待它们变为true后再resolve。
内容的提问来源于stack exchange,提问作者Jus10
相关产品推荐
相关产品推荐

