JS函數(shù)防抖的詳細(xì)解析

這篇文章主要講解了JS函數(shù)防抖的詳細(xì)解析,內(nèi)容清晰明了,對此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會有幫助。

成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供多倫企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、網(wǎng)站制作、html5、小程序制作等業(yè)務(wù)。10年已為多倫眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。

一、什么是函數(shù)防抖

       概念:函數(shù)防抖(debounce),就是指觸發(fā)事件后,在 n 秒內(nèi)函數(shù)只能執(zhí)行一次,如果觸發(fā)事件后在 n 秒內(nèi)又觸發(fā)了事件,則會重新計算函數(shù)延執(zhí)行時間。

       舉個栗子,坐電梯的時候,如果電梯檢測到有人進(jìn)來(觸發(fā)事件),就會多等待 10 秒,此時如果又有人進(jìn)來(10秒之內(nèi)重復(fù)觸發(fā)事件),那么電梯就會再多等待 10 秒。在上述例子中,電梯在檢測到有人進(jìn)入 10 秒鐘之后,才會關(guān)閉電梯門開始運行,因此,“函數(shù)防抖”的關(guān)鍵在于,在 一個事件 發(fā)生 一定時間 之后,才執(zhí)行 特定動作。

二、為什么需要函數(shù)防抖

前端開發(fā)過程中,有一些事件,常見的例如,onresize,scroll,mousemove ,mousehover 等,會被頻繁觸發(fā)(短時間內(nèi)多次觸發(fā)),不做限制的話,有可能一秒之內(nèi)執(zhí)行幾十次、幾百次,如果在這些函數(shù)內(nèi)部執(zhí)行了其他函數(shù),尤其是執(zhí)行了操作 DOM 的函數(shù)(瀏覽器操作 DOM 是很耗費性能的),那不僅會浪費計算機(jī)資源,還會降低程序運行速度,甚至造成瀏覽器卡死、崩潰。這種問題顯然是致命的。

       除此之外,短時間內(nèi)重復(fù)的 ajax 調(diào)用不僅會造成數(shù)據(jù)關(guān)系的混亂,還會造成網(wǎng)絡(luò)擁塞,增加服務(wù)器壓力,顯然這個問題也是需要解決的。

三、函數(shù)防抖如何解決上述問題

       根據(jù)上面對問題的分析,細(xì)細(xì)思索,可以想到如下解決方案。

       函數(shù)防抖的要點,是需要一個 setTimeout 來輔助實現(xiàn),延遲運行需要執(zhí)行的代碼。如果方法多次觸發(fā),則把上次記錄的延遲執(zhí)行代碼用 clearTimeout 清掉,重新開始計時。若計時期間事件沒有被重新觸發(fā),等延遲時間計時完畢,則執(zhí)行目標(biāo)代碼。

四、函數(shù)防抖的代碼實現(xiàn)

       根據(jù)以上分析,我們對 “函數(shù)防抖” 來進(jìn)行簡單的代碼實現(xiàn),如下:

function debounce(fn,wait){
 var timer = null;
 return function(){
  if(timer !== null){
   clearTimeout(timer);
  }
  timer = setTimeout(fn,wait);
 }
}
 
function handle(){
 console.log(Math.random());
}
 
window.addEventListener("resize",debounce(handle,1000));

五、函數(shù)節(jié)流的使用場景

       函數(shù)防抖一般用在什么情況之下呢?一般用在,連續(xù)的事件只需觸發(fā)一次回調(diào)的場合。具體有:

       搜索框搜索輸入。只需用戶最后一次輸入完,再發(fā)送請求;

       用戶名、手機(jī)號、郵箱輸入驗證;

       瀏覽器窗口大小改變后,只需窗口調(diào)整完后,再執(zhí)行 resize 事件中的代碼,防止重復(fù)渲染。

       目前遇到過的用處就是這些,理解了原理與實現(xiàn)思路,小伙伴可以把它運用在任何需要的場合,提高代碼質(zhì)量。

總結(jié)

       函數(shù)防抖其實是分為 “立即執(zhí)行版” 和 “非立即執(zhí)行版” 的,根據(jù)字面意思就可以發(fā)現(xiàn)他們的差別,所謂立即執(zhí)行版就是 觸發(fā)事件后函數(shù)不會立即執(zhí)行,而是在 n 秒后執(zhí)行,如果在 n 秒內(nèi)又觸發(fā)了事件,則會重新計算函數(shù)執(zhí)行時間。 而 “非立即執(zhí)行版” 指的是 觸發(fā)事件后函數(shù)會立即執(zhí)行,然后 n 秒內(nèi)不觸發(fā)事件才能繼續(xù)執(zhí)行函數(shù)的效果。。

       在開發(fā)過程中,我們需要根據(jù)不同的場景來決定我們需要使用哪一個版本的防抖函數(shù),一般來講上述的防抖函數(shù)都能滿足大部分的場景需求。但我們也可以將非立即執(zhí)行版和立即執(zhí)行版的防抖函數(shù)結(jié)合起來,實現(xiàn)最終的雙劍合璧版本的防抖函數(shù),以下為小伙伴們做了簡單的實現(xiàn):

/**
* @desc 函數(shù)防抖---“立即執(zhí)行版本” 和 “非立即執(zhí)行版本” 的組合版本
* @param func 需要執(zhí)行的函數(shù)
* @param wait 延遲執(zhí)行時間(毫秒)
* @param immediate---true 表立即執(zhí)行,false 表非立即執(zhí)行
**/
function debounce(func,wait,immediate) {
let timer;

return function () {
let context = this;
let args = arguments;

if (timer) clearTimeout(timer);
if (immediate) {
var callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait)
if (callNow) func.apply(context, args)
} else {
timer = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}

function handle(){
console.log(Math.random());
}

// window.addEventListener("mousemove",debounce(handle,1000,true)); // 調(diào)用立即執(zhí)行版本
window.addEventListener("mousemove",debounce(handle,1000,false)); // 調(diào)用非立即執(zhí)行版本

看完上述內(nèi)容,是不是對JS函數(shù)防抖的詳細(xì)解析有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)頁標(biāo)題:JS函數(shù)防抖的詳細(xì)解析
分享路徑:http://bm7419.com/article28/jjdpjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、網(wǎng)站排名網(wǎng)站策劃、服務(wù)器托管網(wǎng)站改版、響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化