最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

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

為什么使用防抖

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

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

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

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

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

原理

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

手寫實現(xiàn)

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

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

使用 Lodash 的 _.debounce

在實際項目中,為了減少手寫錯誤并獲得更豐富的功能(如 leading、trailing、cancelflush 等選項),推薦使用成熟的工具庫 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() 方法,可在需要時取消或立即執(zhí)行待定調(diào)用 ([GeeksforGeeks][10])。

完整示例:防抖搜索組件

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

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

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

  • moment.js 計算當(dāng)前一周、一月對應(yīng)日期的實例

    moment.js 計算當(dāng)前一周、一月對應(yīng)日期的實例

    這篇文章主要介紹了moment.js 計算當(dāng)前一周、一月對應(yīng)日期的實例代碼,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Javascript常用小技巧匯總

    Javascript常用小技巧匯總

    這篇文章主要介紹了Javascript常用小技巧,實例匯總了javascript運算符、表達(dá)式及遍歷等常用技巧,需要的朋友可以參考下
    2015-06-06
  • JavaScript中的類與實例實現(xiàn)方法

    JavaScript中的類與實例實現(xiàn)方法

    這篇文章主要介紹了JavaScript中的類與實例實現(xiàn)方法,非常巧妙的模擬了類與實例的實現(xiàn)過程,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • 詳解如何解決使用JSON.stringify時遇到的循環(huán)引用問題

    詳解如何解決使用JSON.stringify時遇到的循環(huán)引用問題

    這篇文章主要介紹了詳解如何解決使用JSON.stringify時遇到的循環(huán)引用問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 原生js開發(fā)的日歷插件

    原生js開發(fā)的日歷插件

    本文主要分享了原生js開發(fā)的日歷插件的示例代碼。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • javascript AutoScroller 函數(shù)類

    javascript AutoScroller 函數(shù)類

    javascript AutoScroller 自動滾動類代碼,學(xué)習(xí)類的朋友可以參考下。
    2009-05-05
  • JavaScript之promise_動力節(jié)點Java學(xué)院整理

    JavaScript之promise_動力節(jié)點Java學(xué)院整理

    這篇文章主要為大家詳細(xì)介紹了JavaScript之promise的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • JavaScript內(nèi)置對象Math與String詳細(xì)介紹

    JavaScript內(nèi)置對象Math與String詳細(xì)介紹

    這篇文章主要介紹了JavaScript內(nèi)置對象Math與String的介紹與使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 最新評論

    宜川县| 五家渠市| 汤阴县| 泾川县| 徐闻县| 寻乌县| 九寨沟县| 夏津县| 延吉市| 青海省| 保亭| 庆元县| 乳山市| 秦安县| 绥中县| 武义县| 左权县| 且末县| 阳高县| 马鞍山市| 南漳县| 万山特区| 洛隆县| 特克斯县| 四子王旗| 威海市| 容城县| 双城市| 吉林省| 郁南县| 额尔古纳市| 泰兴市| 深州市| 镶黄旗| 平舆县| 闻喜县| 合江县| 大渡口区| 卓尼县| 大田县| 志丹县|