在现代前端开发中,防止用户快速重复点击按钮或执行某些操作是一个常见的需求。例如,用户在短时间内连续点击按钮时,我们可能只想执行第一次点击的操作,而忽略后续的重复点击。
为了解决这个问题,我们可以使用一个 锁定机制 来防止函数的多次调用。本文将介绍如何使用 Vue 3 中的 ref 和 async 函数来实现一个 useLockFn 自定义 Hook,它可以防止在短时间内重复执行一个异步操作。
需求分析
有些操作可能会被频繁触发,比如:
• 用户多次点击按钮发起网络请求。
• 连续调用同一个函数导致重复操作(例如,表单提交、数据保存等)。
为了避免这种重复操作,我们需要引入 锁机制,确保同一时刻只执行一次函数。
useLockFn 的实现
useLockFn 是一个高阶函数,它接受一个异步函数 fn 和一个可选的延迟 delay(默认为 600 毫秒)。它返回一个新函数,该函数会:
• 防止在指定的延迟时间内重复调用。
• 在异步操作完成前,锁住该函数,避免重复执行。
import { ref } from 'vue';
type ArgsAny = any[];
type Fn = (...args: ArgsAny) => Promise<any>;
export const useLockFn = (fn: Fn, delay = 600) => {
const lock = ref(false);
const lastDate = ref();
return async (...args: ArgsAny) => {
if (lock.value) return;
const nowDate = new Date();
if (lastDate?.value && nowDate.getTime() - lastDate?.value.getTime() <= delay) {
return;
}
lastDate.value = nowDate;
lock.value = true;
try {
const ret = await fn(...args);
lock.value = false;
return ret;
} catch (error) {
lock.value = false;
throw error;
}
};
};
