如何让防抖后的服务方法支持两次独立调用?
问题分析与解决方案
你遇到的问题本质是Lodash防抖函数的实例共享问题:当你直接把_.debounce()的结果赋值给someService时,整个应用里调用myService.someService的地方都会复用同一个防抖函数实例,这个实例内部的计时器是共享的。所以当ValidatorA调用后1秒内ValidatorB触发,防抖逻辑会重置计时器,最终只执行最后一次请求。
优雅的解决方案:用工厂函数创建独立的防抖实例
不要直接导出防抖后的函数,而是导出一个工厂函数——每次调用这个工厂函数,都会返回一个全新的防抖函数实例,这样每个验证器都有自己独立的计时器,不会互相干扰。
修改你的myService.js:
// myService.js export default { // 改为返回防抖函数的工厂 someService: () => _.debounce(function someService(rule, value, callback) { myApi.get(`check-input/${value}`) .then((response) => { if (response.data.valid) { callback(); } else { callback(new Error('Invalid value')); } }) .catch(() => { callback(new Error('Internal error. Please try later.')); }); }, 2000) };
然后更新验证器的调用方式,每次调用工厂函数获取新的防抖实例:
// 每个验证器都拿到独立的防抖函数 const ValidatorA = myService.someService(); const ValidatorB = myService.someService();
这样当两个输入框触发验证时,它们调用的是完全独立的防抖函数,计时器各自生效,两次请求都会被正常发起。
为什么Object.assign或深克隆没用?
防抖函数的核心状态(计时器ID)是保存在函数的闭包中的,而不是对象的属性里。克隆操作只能复制函数的引用,无法复制闭包内部的状态——所以即使你克隆了myService,调用的还是同一个防抖函数实例,计时器依然共享,自然解决不了问题。
内容的提问来源于stack exchange,提问作者Paweł Jaworowski
相关产品推荐
相关产品推荐

