cqwcns 发表于 2023-1-21 21:53

vue3防抖函数的问题

本帖最后由 cqwcns 于 2023-1-21 22:27 编辑

vue3中,我希望实现函数执行的防抖;
具体场景是当我点击按钮,会触发toDebounce函数,该函数在调用debounce函数来执行myfun。
如果在2秒内重复点击按钮,最终myfun只会执行一次。


我借鉴了网上很多现成的代码,但无论怎么测试,都没有成功。


不知道怎么解决,请各位大佬指教,感谢。



<script setup>
function debounce(fn, delay) {
let timer = null
return function () {
    let content = this;
    let args = arguments;
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn.apply(content, args)
    }, delay)
}
}

function myfun() {
console.log('函数执行了')// 无法执行到这里
}

const toDebounce = () => {
console.log('触发');// 执行到这里
debounce(myfun, 2000);
}
</script>


使用场景说明:

正常来说,防抖主要是用于input的输入。函数执行完全加一些逻辑来实现防抖。
但实际使用的场景是element-plus select-v2组件(远程搜索),它有个input动态生成的,无法使用一般的input防抖。
所以考虑从在远程搜索函数上进行防抖。

吃西瓜的鲨鱼 发表于 2023-1-21 22:39

你调用debounce这个函数是返回一个匿名函数,你并没有调用返回它

爱吃鹅肉饭 发表于 2023-1-21 22:59

兄弟可以考虑把按钮短暂disabled掉,来实现效果

goldli 发表于 2023-1-22 06:35

本帖最后由 goldli 于 2023-1-23 18:52 编辑

无效回复。 已删除

小白白爱吃糖 发表于 2023-1-22 08:20

<script setup>
    let timer = null
    function debounce(fn, delay) {
      return function () {
            let content = this;
            let args = arguments;
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                fn.apply(content, args)
            }, delay)
      }
    }

    function myfun() {
      console.log('函数执行了')// 无法执行到这里
    }

    const toDebounce = () => {
      console.log('触发');// 执行到这里
      debounce(myfun, 2000);
    }
</script>

你只需要把timer放到最外面就行了 因为你放在函数内部,每次执行都是一个全新的声明 timer 跟上次无法产生关系,你应该去了解一下作用域
当timer在外部 你操作的始终是外部的这一个,如果在函数内部声明则会优先考虑当前函数内部的,找不到才会找外面的,所以你每次执行函数都是声明一个全新的timer 所以这里的if(timer) 是没有任何作用的,当放在外部 就可以正常检测到了,因为并不会被覆盖且是同一个

小白白爱吃糖 发表于 2023-1-22 08:25

你在 debounce 里面返回的是一个函数 你只返回不调用 肯定没反应啊 希望这个测试用例能给你帮助
<script setup>
let timer = null;
function debounce(fn, delay) {
return function () {
    let content = this;
    let args = arguments;
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(content, args);
    }, delay);
};
}

function myfun() {
console.log("函数执行了"); // 无法执行到这里
}

const toDebounce = () => {
console.log("触发"); // 执行到这里
debounce(myfun, 2000)();
};
</script>

索马里的海贼 发表于 2023-1-22 10:51

用rxjs吧,一把梭
页: [1]
查看完整版本: vue3防抖函数的问题