useDebounce.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /**
  2. * 防抖函数 - 延迟函数执行,直到事件停止后的一段时间
  3. * @param fn 需要防抖的函数
  4. * @param wait 等待时间(毫秒)
  5. * @param options 配置选项
  6. * @returns 防抖后的函数
  7. */
  8. export function useDebounce<T extends (...args: any[]) => any>(
  9. fn: T,
  10. wait: number,
  11. options?: {
  12. /** 是否立即执行第一次调用 */
  13. immediate?: boolean;
  14. }
  15. ): {
  16. /** 防抖后的函数 */
  17. (this: any, ...args: Parameters<T>): void;
  18. /** 取消当前等待执行的函数调用 */
  19. cancel: () => void;
  20. /** 立即执行当前等待的函数调用 */
  21. flush: () => void;
  22. } {
  23. let timeoutId: ReturnType<typeof setTimeout> | null = null;
  24. const immediate = options?.immediate ?? false;
  25. const debounced = function (this: any, ...args: Parameters<T>) {
  26. // 清除之前的定时器
  27. if (timeoutId !== null) {
  28. clearTimeout(timeoutId);
  29. }
  30. // 立即执行模式
  31. if (immediate && timeoutId === null) {
  32. fn.apply(this, args);
  33. }
  34. // 设置新的定时器
  35. timeoutId = setTimeout(() => {
  36. // 非立即执行模式,或者是之后的调用
  37. if (!immediate || timeoutId !== null) {
  38. fn.apply(this, args);
  39. }
  40. timeoutId = null;
  41. }, wait);
  42. };
  43. /**
  44. * 取消当前等待执行的函数调用
  45. */
  46. debounced.cancel = function () {
  47. if (timeoutId !== null) {
  48. clearTimeout(timeoutId);
  49. timeoutId = null;
  50. }
  51. };
  52. /**
  53. * 立即执行当前等待的函数调用
  54. */
  55. debounced.flush = function () {
  56. if (timeoutId !== null) {
  57. clearTimeout(timeoutId);
  58. fn();
  59. timeoutId = null;
  60. }
  61. };
  62. return debounced;
  63. }