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

Angular中返回Promise<boolean>的方法如何实现防抖避免重复点击跳页

解决方案

方案1:执行状态锁(推荐用于路由跳转场景)

逻辑最简单无额外依赖,通过标记位屏蔽跳转过程中的重复请求:

// 服务内新增私有状态标记
private isNavigating = false;

goToNextRoute = async (queryParams?: Params): Promise<boolean> => {
  if (this.isNavigating) return false;
  try {
    this.isNavigating = true;
    return await this.routeRecursive(this.getNextRoute, queryParams);
  } finally {
    this.isNavigating = false;
  }
}
  • 优势:无延迟,只要前一次跳转未完成就直接忽略后续触发,完全避免连续点击多跳的问题
  • 适用场景:路由跳转、表单提交等需要立即响应但不允许重复执行的操作

方案2:自定义Promise防抖函数

如果需要和debounceTime一致的「等待用户停止操作后再执行」的效果,可直接实现通用Promise防抖工具:

// 通用Promise防抖工具
function debouncePromise<T extends (...args: any[]) => Promise<any>>(
  fn: T,
  delay: number
): (...args: Parameters<T>) => ReturnType<T> {
  let timer: NodeJS.Timeout | null = null;
  return function(...args: Parameters<T>): ReturnType<T> {
    if (timer) clearTimeout(timer);
    return new Promise((resolve, reject) => {
      timer = setTimeout(async () => {
        try {
          const res = await fn.apply(this, args);
          resolve(res);
        } catch (err) {
          reject(err);
        }
      }, delay);
    }) as ReturnType<T>;
  }
}

// 改造原方法,比如设置300ms防抖
goToNextRoute = debouncePromise((queryParams?: Params): Promise<boolean> => 
  this.routeRecursive(this.getNextRoute, queryParams), 300);
  • 优势:无需引入RxJS,效果和RxJS的debounceTime完全一致
  • 适用场景:搜索输入、按钮点击防抖等需要延迟执行的场景

方案3:配合RxJS使用(项目已引入RxJS可选)

如果项目本身已经接入RxJS,可以把Promise转Observable后直接使用debounceTime操作符:

import { fromEvent } from 'rxjs';
import { debounceTime, switchMap } from 'rxjs/operators';

// 绑定按钮点击事件时用Observable处理
fromEvent(提交按钮DOM引用, 'click')
  .pipe(
    debounceTime(300),
    switchMap(() => this.goToNextRoute(/* 传递你的queryParams参数 */))
  )
  .subscribe()

内容的提问来源于stack exchange,提问作者Younes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:15:03