返回课程

防抖装饰器

重要性:5

debounce(f, ms) 装饰器的结果是一个包装器,它会暂停对 f 的调用,直到有 ms 毫秒的空闲时间(没有调用,“冷却时间”),然后用最新的参数调用 f 一次。

换句话说,debounce 就像一个秘书,接收“电话”,并等待 ms 毫秒的安静时间。只有在那之后,它才会将最新的通话信息转交给“老板”(调用实际的 f)。

例如,我们有一个函数 f,并用 f = debounce(f, 1000) 替换它。

如果包装函数在 0ms、200ms 和 500ms 时被调用,然后没有调用,那么实际的 f 将只在 1500ms 时被调用一次。也就是说:在上次调用后的 1000ms 冷却时间之后。

…并且它将获取最后一次调用的参数,其他调用将被忽略。

以下是它的代码(使用来自 Lodash 库 的防抖装饰器)

let f = _.debounce(alert, 1000);

f("a");
setTimeout( () => f("b"), 200);
setTimeout( () => f("c"), 500);
// debounced function waits 1000ms after the last call and then runs: alert("c")

现在举一个实际的例子。假设用户输入了一些内容,我们希望在输入完成时向服务器发送请求。

没有必要为每个输入的字符发送请求。相反,我们希望等待,然后处理整个结果。

在网页浏览器中,我们可以设置一个事件处理程序——一个在输入字段每次更改时被调用的函数。通常,事件处理程序会非常频繁地被调用,对于每个输入的键都会被调用。但是,如果我们用 1000ms 对它进行 防抖,那么它将只在最后一次输入后 1000ms 被调用一次。

在这个实时示例中,处理程序将结果放入下面的框中,试试看

看到了吗?第二次输入调用了防抖函数,因此它的内容在最后一次输入后 1000ms 被处理。

所以,防抖 是处理一系列事件的好方法:无论是按键序列、鼠标移动还是其他东西。

它在最后一次调用后等待给定的时间,然后运行它的函数,该函数可以处理结果。

任务是实现 防抖 装饰器。

提示:如果你仔细想想,这只是一两行代码 :)

打开一个带有测试的沙箱。

function debounce(func, ms) {
  let timeout;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, arguments), ms);
  };
}

防抖 的调用返回一个包装器。当被调用时,它会安排在给定的 ms 后调用原始函数,并取消之前这样的超时。

在沙箱中打开带有测试的解决方案。