如何控制Promise.all任务:暂停全部、单任务更新共享变量、恢复所有任务
解决方案:基于刷新锁实现并发任务的共享值单例刷新
核心思路是通过一个刷新锁(Promise实例)控制只有第一个检测到值过期的任务执行刷新操作,其余任务等待刷新完成后再继续执行。具体实现如下:
1. 初始化类变量
在构造函数中添加刷新锁变量,标记当前是否有正在进行的刷新操作:
class MyClass { constructor() { this.sharedValue = null; // 刷新锁:null表示无刷新操作,否则为正在执行的refreshSharedValue Promise this.refreshLock = null; } }
2. 封装值有效性检查方法
新增异步方法统一处理过期判断、锁竞争和刷新逻辑,确保同一时间仅一个刷新操作执行:
async ensureSharedValueValid() { // 已有刷新任务在执行,直接等待其完成 if (this.refreshLock) { await this.refreshLock; return; } // 替换成你的实际过期判断逻辑 const isExpired = !this.sharedValue || Date.now() > this.sharedValue.expireTime; if (!isExpired) return; // 创建刷新锁,执行刷新操作 this.refreshLock = this.refreshSharedValue(); try { await this.refreshLock; } finally { // 刷新完成后清空锁,允许后续任务触发新刷新 this.refreshLock = null; } }
3. 修改并发任务逻辑
每个任务先调用ensureSharedValueValid()确保值有效,再执行业务逻辑:
async doWork(taskList) { await Promise.all(taskList.map(async (taskData) => { // 前置等待共享值变为有效状态 await this.ensureSharedValueValid(); // 此处执行业务逻辑,sharedValue已确保有效 console.log(`处理任务:${taskData},使用值:${this.sharedValue.value}`); // ...其他业务操作 })); }
4. 完善刷新方法示例
假设refreshSharedValue需要从外部获取新值并设置过期时间:
async refreshSharedValue() { // 模拟异步刷新(比如调用API) const newValue = await new Promise(resolve => { setTimeout(() => resolve({ value: Math.random(), expireTime: Date.now() + 5000 // 5秒后过期 }), 1000); }); this.sharedValue = newValue; console.log('共享值已刷新'); }
逻辑说明
- 多个并发任务同时检测到过期时,第一个进入检查方法的任务会创建刷新锁,其余任务自动等待锁完成。
- 刷新完成后锁被清空,后续任务若再检测到过期,会重新触发新的刷新流程。
- 无需中断
Promise.all,通过前置异步等待让所有任务自动对齐到有效状态后执行。
内容的提问来源于stack exchange,提问作者luke.dev
相关产品推荐
相关产品推荐

