程序员的知识教程库

网站首页 > 教程分享 正文

debounce(防抖)和throttle(节流)(防抖和节流是闭包吗)

henian88 2024-08-13 06:16:01 教程分享 19 ℃ 0 评论

在处理诸如 resize、scroll、mousemove、keydown / keyup / keypress 等事件和输入框内容校验等操作的时候,通常我们不希望这些事件太过频繁地触发,尤其是监听程序中涉及到大量的计算或者有非常耗费资源的操作。此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少触发的频率,同时又不影响实际效果。

debounce 防抖

在 JavaScript 中,debounce 函数所做的事情就是,在用户停止某个操作一段时间之后才执行相应的监听函数,而不是在用户操作的过程当中,浏览器触发多少次事件,就执行多少次监听函数。

从上图中我们可以看到,当持续触发事件时,debounce会合并事件且不会去触发事件,当一定时间内没有触发再这个事件时,才真正去触发事件。

/**

*

* @param fn {Function} 实际要执行的函数

* @param delay {Number} 延迟时间,也就是阈值,单位是毫秒(ms)

*

* @return {Function} 返回一个防抖的函数

*/

function debounce(fn, delay) {

var ctx;

var args;

var timer = null;

var later = function () {

fn.apply(ctx, args);

// 当事件真正执行后,清空定时器

timer = null;

};

return function () {

ctx = this;

args = arguments;

// 当持续触发事件时,若发现事件触发的定时器已设置时,则清除之前的定时器

if (timer) {

clearTimeout(timer);

timer = null;

}

// 重新设置事件触发的定时器

timer = setTimeout(later, delay);

};

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

throttle 节流

当持续触发事件时,保证隔间时间触发一次事件。

上图中绿色块表示触发一次事件,持续触发事件时,throttle会合并一定时间内的事件,并在该时间结束时真正去触发一次事件。

/**

*

* @param fn {Function} 实际要执行的函数

* @param delay {Number} 执行间隔,单位是毫秒(ms)

*

* @return {Function} 返回一个“节流”函数

*/

function throttle(fn, delay) {

var ctx;

var args;

// 记录上次触发事件

var previous = Date.now();

var later = function () {

fn.apply(ctx, args);

};

return function () {

ctx = this;

args = arguments;

var now = Date.now();

// 本次事件触发与上一次的时间比较

var diff = now - previous - delay;

// 如果隔间时间超过设定时间,即再次设置事件触发的定时器

if (diff >= 0) {

// 更新最近事件触发的时间

previous = now;

setTimeout(later, delay);

}

};

}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表