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
相关产品推荐
相关产品推荐

