如何避免每次点击创建新Promise 防止异步逻辑重复执行
重复点击触发重复执行问题解决方案
核心实现思路是在异步逻辑执行周期内增加拦截判断,避免重复发起高负载任务,常用两种实现方式:
方案1:布尔状态锁(实现最简单,适配绝大多数场景)
在类中增加执行状态标记,点击触发时先判断标记状态,若处于执行中直接拦截返回,逻辑执行完成后再重置标记。
// 类中新增状态标记 private isProcessing = false; public clickEvent() { // 执行中直接拦截,不往下执行 if (this.isProcessing) return; // 标记为执行中 this.isProcessing = true; this.createIframe() .then((iframe) => { // 原有高负载异步业务逻辑 }) .catch((err) => { // 按需处理异常 console.error('执行出错', err); }) .finally(() => { // 无论成功失败,都重置标记,允许下一次触发 this.isProcessing = false; }); }
注意:必须在finally回调中重置状态,否则异步逻辑抛错时会导致标记永久为true,后续点击完全失效。如果需要交互反馈,可在拦截分支增加轻提示,告知用户操作正在处理中。
方案2:缓存Pending状态Promise(适合多入口调用场景)
如果这个方法不止点击会触发,还有其他业务逻辑可能同时调用,可以直接缓存正在执行的Promise实例,后续调用直接复用当前正在执行的任务,不会重复执行逻辑。
// 类中新增Promise缓存标记 private pendingTask: Promise<any> | null = null; public clickEvent() { // 存在正在执行的任务时直接返回该任务,不新建逻辑 if (this.pendingTask) return this.pendingTask; this.pendingTask = this.createIframe() .then((iframe) => { // 原有高负载异步业务逻辑 return iframe; }) .finally(() => { // 执行完成后清空缓存,允许下一次新的触发 this.pendingTask = null; }); return this.pendingTask; }
补充优化建议
如果是绑定在DOM按钮上的点击事件,可以搭配UI层面的禁用状态:点击触发后直接给按钮元素加disabled属性,异步逻辑执行完成后再移除禁用,从交互层面避免用户快速重复点击,和上面的逻辑锁搭配使用稳妥度更高。
内容的提问来源于stack exchange,提问作者Anastasia
相关产品推荐
相关产品推荐

