Skip to content

防抖和节流

更新: 2025/3/18 14:37:35 字数: 0 字

函数防抖

使用场景:频繁调用某个函数,造成了效率问题,需要的结果以最后一次为准。

定义:当事件触发后,会设置一个定时器,在指定的延迟时间之后再执行相应的操作, 如果在延迟时间内再次触发了同一个事件,那么就会清除掉之前的定时器,并查询设置新的定时器,直到事件触发完成。

js
// 场景:
// 我有一个布局,比如说是照片墙的布局,当我改变浏览器的大小的时候,需要
// 重新使用 js 去计算其布局。
window.onresize = layout 
// 当页面大小发生变化时就执行 layout 函数来重新布局
// 但是这样会造成一个问题页面非常卡顿。因为它会触发的非常频繁,回去不断的调用
// layout 方法


// 修改
let timerId;
window.onresize = () => {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
        layout();
    }, 5000);
}
// 修改为通用的函数
const d_layout = debounce(layout);
function debounce(fn, time = 5000){
    let timerId;
    // 这里用 普通函数因为要控制 this 指向
    return function (...args) {
        clearnTime(timerId);
        // 这里用箭头函数保证函数里面的 this 和外面的 this 一致
        timerId = setTimeout(() => {
            // 改变 fn 的 this 指向
            fn.apply(this, args);
        }, time)
    }
}
// 1. 我们还要保证函数可以传递参数
// 2. this 指向不能出问题 --- 及最后里面的 fn 的 this 指向必须是和 
// 调用 d_layout 的 this 指向相同

函数节流

方案:

  1. 开始时等待 5s 之后执行,如果这 5s 内来了新的东西,那么我们什么也不做,继续等待。
  2. 开始时立即执行,而下一次执行就要等一段时间

定义:当事件触发后,事件处理函数会在固定的时间间隔内执行,即使时间被频繁触发也是如此。

js
/* 场景:
 * 我有一个布局,比如说是照片墙的布局,当我改变浏览器的大小的时候,需要
 * 重新使用 js 去计算其布局。
 */
window.onresize = layout 
// 当页面大小发生变化时就执行 layout 函数来重新布局
// 但是这样会造成一个问题页面非常卡顿。因为它会触发的非常频繁,回去不断的调用
// layout 方法


// 修改
let timerId;
window.onresize = () => {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
        layout();
    }, 5000);
}
// 修改为通用的函数
const d_layout = debounce(layout);
function debounce(fn, time = 5000){
    let timerId;
    // 这里用 普通函数因为要控制 this 指向
    return function (...args) {
        clearnTime(timerId);
        // 这里用箭头函数保证函数里面的 this 和外面的 this 一致
        timerId = setTimeout(() => {
            // 改变 fn 的 this 指向
            fn.apply(this, args);
        }, time)
    }
}
// 1. 我们还要保证函数可以传递参数
// 2. this 指向不能出问题 --- 及最后里面的 fn 的 this 指向必须是和 
// 调用 d_layout 的 this 指向相同

道友再会.