1. 程式人生 > 其它 >函式防抖與函式節流(閉包例項)

函式防抖與函式節流(閉包例項)

函式防抖

/**
 * @function debounce 函式防抖
 * @param {Function} fn 需要防抖的函式
 * @param {Number} interval 間隔時間
 * @return {Function} 經過防抖處理的函式
 * */
function debounce(fn, interval) {
    let timer = null; // 定時器
    return function() {
        // 清除上一次的定時器
        clearTimeout(timer);
        // 拿到當前的函式作用域
        let _this = this
; // 拿到當前函式的引數陣列 let args = Array.prototype.slice.call(arguments, 0); // 開啟倒計時定時器 timer = setTimeout(function() { // 通過apply傳遞當前函式this,以及引數 fn.apply(_this, args); // 預設300ms執行 }, interval || 300) } }
  • 概念:就是指觸發事件後在 n 秒內函式只能執行一次,如果在 n 秒內又觸發了事件,則會重新計算函式執行時間。通俗一點:在一段固定的時間內,只能觸發一次函式,在多次觸發事件時,只執行最後一次。

  • 使用時機:搜尋功能,在使用者輸入結束以後才開始傳送搜尋請求,可以使用函式防抖來實現;

函式節流

/**
 * @function throttle 函式節流
 * @param {Function} fn 需要節流的函式
 * @param {Number} interval 間隔時間
 * @return {Function} 經過節流處理的函式
 * */
function throttle(fn, interval) {
    let timer = null; // 定時器
    let firstTime = true; // 判斷是否是第一次執行
    // 利用閉包
    return
function() { // 拿到函式的引數陣列 let args = Array.prototype.slice.call(arguments, 0); // 拿到當前的函式作用域 let _this = this; // 如果是第一次執行的話,需要立即執行該函式 if(firstTime) { // 通過apply,綁定當前函式的作用域以及傳遞引數 fn.apply(_this, args); // 修改標識為null,釋放記憶體 firstTime = null; } // 如果當前有正在等待執行的函式則直接返回 if(timer) return; // 開啟一個倒計時定時器 timer = setTimeout(function() { // 通過apply,綁定當前函式的作用域以及傳遞引數 fn.apply(_this, args); // 清除之前的定時器 timer = null; // 預設300ms執行一次 }, interval || 300) } }
  • 概念:就是限制一個函式在一定時間內只能執行一次。

  • 使用時機:①改變瀏覽器視窗尺寸,可以使用函式節流,避免函式不斷執行;②滾動條scroll事件,通過函式節流,避免函式不斷執行。

函式節流與函式防抖的區別:

案例:設定一個間隔時間為一秒,在一分鐘內,不斷的移動滑鼠,讓它觸發一個函式,列印一些內容。

  • 函式防抖:會列印1次,在滑鼠停止移動的一秒後列印。

  • 函式節流:會列印60次,因為在一分鐘內有60秒,每秒會觸發一次。

  • 總結:節流是為了限制函式的執行次數,而防抖是為了限制函式的執行時機。

函式節流與函式防抖的使用

此處使用一個物件的方法,主要為了測試this指向繫結的問題,呼叫的時候傳遞引數問題等。

function log(a,b) {
    console.log(a,b);
    console.log(this);
}
const throttleLog = throttle(log, 1000);
const debounceLog = debounce(log, 1000);
let a  = {
    b: throttleLog,
    c: debounceLog
};
document.body.onmousemove = function() {
    a.b('throttle', 'log');
    a.c('debounce', 'log');
};