如何判断async函数是否正在运行 存在运行实例时监听并返回其结果
实现方案
核心逻辑是给目标异步函数挂载一个内部状态,存储当前正在运行的 Promise 实例:
- 首次调用函数时,生成运行中的 Promise 实例存在函数属性上,执行完成后自动清空该属性
- 后续调用时如果检测到已有正在运行的 Promise 实例,直接返回该实例,无需重复执行
- 同时满足要求的等待5秒后返回
foo = foo + 1的逻辑
完整代码实现
// 示例全局变量foo,可根据实际需求调整作用域 let foo = 0; async function a() { // 如果已有正在运行的实例,直接返回 if (a.runningPromise) { return a.runningPromise; } // 生成新的运行实例,挂载到函数属性上 a.runningPromise = new Promise((resolve, reject) => { // 模拟5秒等待逻辑 setTimeout(() => { try { foo = foo + 1; resolve(foo); } catch (err) { reject(err); } finally { // 无论执行成功还是失败,运行完成后清空实例,下次调用可以重新执行 delete a.runningPromise; } }, 5000); }); return a.runningPromise; }
效果验证
你可以用以下代码测试效果:
// 同时调用3次函数a (async () => { const res1 = a(); const res2 = a(); const res3 = a(); console.log(await res1); // 输出1 console.log(await res2); // 同样输出1,没有重复执行,共用第一个运行实例的结果 console.log(await res3); // 同样输出1 // 等之前的实例运行完成后,再调用才会重新执行 setTimeout(async () => { console.log(await a()); // 输出2,此时是全新的执行实例 }, 6000); })();
逻辑说明
- 利用函数本身作为状态存储的载体,不需要额外定义全局变量存储运行状态
- Promise 状态一旦敲定就会缓存结果,所有 await 同一个 Promise 的调用都会拿到相同的返回值
- 内置 finally 逻辑保证无论执行成功还是失败,都会清空运行状态,不会影响后续正常调用
内容的提问来源于stack exchange,提问作者rendom
相关产品推荐
相关产品推荐

