欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

前端函數(shù)防抖實(shí)現(xiàn)完整實(shí)例詳解

 更新時(shí)間:2025年08月19日 09:59:24   作者:思揚(yáng)0928  
函數(shù)防抖(Debounce)是一種優(yōu)化高頻觸發(fā)事件的技術(shù),通過延遲執(zhí)行函數(shù),直到事件停止觸發(fā)后的指定時(shí)間間隔,這篇文章主要介紹了前端函數(shù)防抖實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在現(xiàn)代 Web 應(yīng)用中,函數(shù)防抖(debounce)是一種常見且高效的性能優(yōu)化手段,用于限制高頻事件觸發(fā)下的函數(shù)調(diào)用次數(shù),從而減少不必要的計(jì)算、網(wǎng)絡(luò)請求或 DOM 操作。本文將從“為什么使用防抖”切入,介紹典型的應(yīng)用場景,深入解析防抖原理,并給出從零實(shí)現(xiàn)到在實(shí)際項(xiàng)目中使用 Lodash 的完整代碼示例,幫助你快速掌握前端防抖技術(shù)。

為什么使用防抖

函數(shù)防抖的核心思想是在連續(xù)觸發(fā)的事件停止后,僅執(zhí)行最后一次調(diào)用,以避免頻繁觸發(fā)帶來的性能問題 ([MDN Web Docs][1])。
在不使用防抖的情況下,例如在 input 輸入事件或 window.resize 事件中直接調(diào)用邏輯,頁面可能會因短時(shí)間內(nèi)大量調(diào)用而出現(xiàn)卡頓或請求風(fēng)暴 ([GeeksforGeeks][2])。

通過防抖,可以讓函數(shù)在用戶停止輸入、滾動或調(diào)整窗口大小后的一定延遲內(nèi)才執(zhí)行,極大提高資源利用效率并提升用戶體驗(yàn) ([Medium][3])。

函數(shù)防抖的應(yīng)用場景

  1. 輸入框?qū)崟r(shí)搜索建議
    在用戶輸入關(guān)鍵詞時(shí)觸發(fā)搜索接口,若不加限制,每次 keyup 都會發(fā)起請求,極易導(dǎo)致接口壓力過大。使用防抖后,只在用戶停止輸入(如 300ms)后才發(fā)送請求,有效降低調(diào)用次數(shù) ([自由代碼營][4])。
  2. 按鈕防連點(diǎn)
    對于提交表單或支付按鈕,連續(xù)點(diǎn)擊可能導(dǎo)致多次提交。給點(diǎn)擊事件綁定防抖函數(shù),可在用戶短時(shí)間內(nèi)多次點(diǎn)擊時(shí)只執(zhí)行一次提交操作 ([DEV Community][5])。
  3. 窗口大小調(diào)整(resize)
    當(dāng)頁面布局需根據(jù)窗口大小實(shí)時(shí)計(jì)算或重繪時(shí),resize 事件會頻繁觸發(fā),添加防抖能減少重繪次數(shù),提升性能 ([Medium][6])。
  4. 滾動監(jiān)聽
    結(jié)合無限滾動或懶加載,當(dāng)用戶滾動頁面時(shí)應(yīng)控制數(shù)據(jù)加載頻率,避免重復(fù)請求或過度渲染 ([Medium][3])。

函數(shù)防抖原理與手寫實(shí)現(xiàn)

原理

防抖函數(shù)通過內(nèi)部維護(hù)一個(gè)定時(shí)器 ID,每次調(diào)用時(shí)先清除之前的定時(shí)器,再啟動一個(gè)新的延遲執(zhí)行定時(shí)器;只有在最后一次調(diào)用后的延遲時(shí)間到達(dá)后,才真正執(zhí)行目標(biāo)函數(shù) ([GeeksforGeeks][2], [Gist][7])。

手寫實(shí)現(xiàn)

/**
 * 簡易版防抖函數(shù)
 * @param {Function} func - 需要防抖的函數(shù)
 * @param {number} wait - 延遲時(shí)間(毫秒)
 * @returns {Function} - 防抖后返回的新函數(shù)
 */
function debounce(func, wait) {
  let timeoutId;                                 // 聲明定時(shí)器 ID
  return function(...args) {                    // 返回一個(gè)閉包函數(shù)
    clearTimeout(timeoutId);                     // 清除上一次定時(shí)器
    timeoutId = setTimeout(() => {               // 啟動新的定時(shí)器
      func.apply(this, args);                    // 延遲執(zhí)行目標(biāo)函數(shù)
    }, wait);
  };
}

上述代碼利用 JavaScript 閉包,讓每個(gè)防抖函數(shù)維護(hù)獨(dú)立的 timeoutId,在多次調(diào)用時(shí)只有最后一次延遲結(jié)束后觸發(fā) ([Stack Overflow][8])。

使用 Lodash 的 _.debounce

在實(shí)際項(xiàng)目中,為了減少手寫錯(cuò)誤并獲得更豐富的功能(如 leading、trailing、cancel、flush 等選項(xiàng)),推薦使用成熟的工具庫 Lodash 的 _.debounce 方法 ([Lodash][9])。

# 安裝 lodash.debounce 子模塊
npm install lodash.debounce
import debounce from 'lodash.debounce';

/** 
 * 在搜索框中使用防抖 
 * 當(dāng)用戶停止輸入 300ms 后才觸發(fā)搜索 
 */
const searchInput = document.getElementById('search');
function onSearch(query) {
  // 發(fā)送搜索請求
  console.log('搜索關(guān)鍵詞:', query);
}
const debouncedSearch = debounce(onSearch, 300, { leading: false, trailing: true });

searchInput.addEventListener('input', (e) => {
  debouncedSearch(e.target.value);
});
  • leading: 是否在延遲開始前調(diào)用一次,默認(rèn) false。
  • trailing: 是否在延遲結(jié)束后調(diào)用一次,默認(rèn) true
  • 返回的函數(shù)還擁有 cancel()flush() 方法,可在需要時(shí)取消或立即執(zhí)行待定調(diào)用 ([GeeksforGeeks][10])。

完整示例:防抖搜索組件

下面給出一個(gè)完整的示例,包括 HTML、樣式與 JavaScript 代碼,你可以直接復(fù)制運(yùn)行:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Debounce Demo</title>
  <style>
    body { font-family: sans-serif; padding: 2rem; }
    #results { margin-top: 1rem; }
    .item { padding: 0.5rem 0; border-bottom: 1px solid #eee; }
  </style>
</head>
<body>
  <h1>Debounce 搜索示例</h1>
  <input id="search" type="text" placeholder="輸入關(guān)鍵詞…" autocomplete="off" />
  <div id="results"></div>
  <script type="module">
    import debounce from 'lodash.debounce';

    const search = document.getElementById('search');
    const results = document.getElementById('results');

    // 模擬異步搜索函數(shù)
    async function fetchResults(query) {
      // 假數(shù)據(jù)
      return ['蘋果', '香蕉', '橘子', '西瓜']
        .filter(item => item.includes(query));
    }

    async function handleSearch(query) {
      const list = await fetchResults(query);
      results.innerHTML = list.map(item => `<div class="item">${item}</div>`).join('');
    }

    // 300ms 防抖,禁止 leading,允許 trailing
    const debouncedHandle = debounce(handleSearch, 300, { leading: false });

    search.addEventListener('input', e => {
      const q = e.target.value.trim();
      if (q) debouncedHandle(q);
      else results.innerHTML = '';
    });
  </script>
</body>
</html>

結(jié)語

函數(shù)防抖是前端性能優(yōu)化中的一項(xiàng)基礎(chǔ)技術(shù),適用于各種需要限制高頻事件調(diào)用的場景,通過簡單的定時(shí)器邏輯或成熟的 Lodash 工具庫,就能快速落地。掌握防抖和其“兄弟”節(jié)流(throttle),能讓你的應(yīng)用在面對頻繁用戶交互時(shí)依然保持流暢、穩(wěn)定。歡迎在項(xiàng)目中實(shí)踐并根據(jù)業(yè)務(wù)需求調(diào)整參數(shù),實(shí)現(xiàn)更靈活的性能優(yōu)化。

到此這篇關(guān)于前端函數(shù)防抖實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)前端函數(shù)防抖實(shí)現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript實(shí)現(xiàn)彈性導(dǎo)航效果

    JavaScript實(shí)現(xiàn)彈性導(dǎo)航效果

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)彈性導(dǎo)航效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 微信小程序picker組件關(guān)于objectArray數(shù)據(jù)類型的綁定方法

    微信小程序picker組件關(guān)于objectArray數(shù)據(jù)類型的綁定方法

    這篇文章主要介紹了微信小程序picker組件關(guān)于objectArray數(shù)據(jù)類型的綁定方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • javascript中如何快速獲取數(shù)組最后一個(gè)值

    javascript中如何快速獲取數(shù)組最后一個(gè)值

    這篇文章主要介紹了javascript中如何快速獲取數(shù)組最后一個(gè)值問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • JS短路原理的應(yīng)用示例 精簡代碼的途徑

    JS短路原理的應(yīng)用示例 精簡代碼的途徑

    正如標(biāo)題所言,js中||和&&的特性幫我們精簡了代碼的同時(shí),也帶來了代碼可讀性的降低。這就需要我們自己來權(quán)衡了,下面有個(gè)不錯(cuò)的示例
    2013-12-12
  • webpack DllPlugin xxx is not defined解決辦法

    webpack DllPlugin xxx is not defined解決辦法

    這篇文章主要介紹了webpack DllPlugin xxx is not defined解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 利用純JS實(shí)現(xiàn)JSON轉(zhuǎn)CSV的技巧全攻略

    利用純JS實(shí)現(xiàn)JSON轉(zhuǎn)CSV的技巧全攻略

    在數(shù)據(jù)處理和導(dǎo)出方面,JSON 和 CSV 格式是兩個(gè)常見的角色,今天,我們將介紹如何在純 JavaScript 中,利用開源庫 @json2csv/plainjs 輕松實(shí)現(xiàn)從 JSON 轉(zhuǎn)換到 CSV,幫助你高效處理數(shù)據(jù),需要的朋友可以參考下
    2025-06-06
  • Eclipse編輯jsp、js文件時(shí)卡死現(xiàn)象的解決辦法匯總

    Eclipse編輯jsp、js文件時(shí)卡死現(xiàn)象的解決辦法匯總

    使用Eclipse編輯jsp、js文件時(shí),經(jīng)常出現(xiàn)卡死現(xiàn)象,在網(wǎng)上百度了N次,經(jīng)過N次優(yōu)化調(diào)整后,卡死現(xiàn)象逐步好轉(zhuǎn),下面通過腳本之家平臺給大家分享幾種解決辦法,需要的朋友參考下
    2016-02-02
  • js彈出窗口返回值的簡單實(shí)例

    js彈出窗口返回值的簡單實(shí)例

    下面小編就為大家?guī)硪黄猨s彈出窗口返回值的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05
  • JS保留兩位小數(shù) 四舍五入函數(shù)的小例子

    JS保留兩位小數(shù) 四舍五入函數(shù)的小例子

    這篇文章主要介紹了JS保留兩位小數(shù) 四舍五入函數(shù)的小例子,有需要的朋友可以參考一下
    2013-11-11
  • ES6箭頭函數(shù)和擴(kuò)展實(shí)例分析

    ES6箭頭函數(shù)和擴(kuò)展實(shí)例分析

    這篇文章主要介紹了ES6箭頭函數(shù)和擴(kuò)展,結(jié)合實(shí)例形式分析了ES6箭頭函數(shù)和擴(kuò)展基本功能、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-05-05

最新評論