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

如何避免每次点击创建新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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:31:05