V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Gaays
V2EX  ›  JavaScript

关于防抖函数有个疑问

  •  
  •   Gaays · 2021-11-05 10:15:03 +08:00 · 3428 次点击
    这是一个创建于 1099 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在网上查到的简单的防抖函数实现是这样的,试了一下确实可以实现防抖,但是我没搞明白多次调用函数每次 timer 不是都会新建一个并赋值为 0 吗?为什么可以把 timer 做为判断标志?

    const debounce = (func, wait = 50) => {
      let timer = 0
      return function(...args) {
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
          func.apply(this, args)
        }, wait)
      }
    }
    
    11 条回复    2021-11-05 17:51:16 +08:00
    cxe2v
        1
    cxe2v  
       2021-11-05 10:21:17 +08:00
    你使用这个 debounce 的时候,是不是这样
    ```
    funcA = debounce(yourfunction,100)
    ```
    这一步将 yourfunction 加入了防抖函数的内部,然后你调用是调用的 funcA ,当 funcA 被调用时,实际上你是在执行
    ```
    function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
    func.apply(this, args)
    }, wait)
    }
    ```
    你注意这里的 timer ,就是同一个 timer
    lalalaqwer
        2
    lalalaqwer  
       2021-11-05 10:21:21 +08:00
    闭包
    你可以看作每次 debounce 的调用都会创建一个空间出来,里面有一个 timer ,后面你调用的是 debounce 返回的那个函数,那个函数就把 debounce 创建的空间内的 timer 当作判断标志。
    loading
        3
    loading  
       2021-11-05 10:55:45 +08:00
    cwp374240920
        4
    cwp374240920  
       2021-11-05 11:03:49 +08:00 via Android
    你用的是他 return 出来的函数,不是防抖包的这个函数
    2i2Re2PLMaDnghL
        5
    2i2Re2PLMaDnghL  
       2021-11-05 11:04:53 +08:00
    在 SICP 应该是第一章里的基本操作
    新建 timer 的时间是在调用 debounce 的时候,而不是调用 func 的时候。
    letwewell
        6
    letwewell  
       2021-11-05 11:30:21 +08:00
    debounce 只调用一次。 使用闭包返回的函数才是多次执行的
    qaqLjj
        7
    qaqLjj  
       2021-11-05 13:51:09 +08:00 via Android
    闭包
    Curtion
        8
    Curtion  
       2021-11-05 14:06:38 +08:00
    debounce 函数只会调一次,需要做防抖的函数应该是 func
    dfkjgklfdjg
        9
    dfkjgklfdjg  
       2021-11-05 14:15:23 +08:00
    闭包原理,所以你后续执行的其实只是 return 出来的匿名函数,其中的 timer 是闭包的父级变量。
    function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
    func.apply(this, args)
    }, wait)
    }
    Gaays
        10
    Gaays  
    OP
       2021-11-05 16:19:51 +08:00
    @cxe2v
    @lalalaqwer
    @dfkjgklfdjg
    谢谢详细解答我明白了
    Kasumi20
        11
    Kasumi20  
       2021-11-05 17:51:16 +08:00
    怎么拿到返回值,我觉得应该加入 Promise 来实现
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2840 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 02:11 · PVG 10:11 · LAX 18:11 · JFK 21:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.