前端筆試題之手寫防抖節(jié)流
這個在線下筆試還是挺常見的,不過我看春招筆試題幾乎沒遇到過。實(shí)際開發(fā)中用的也多,所以學(xué)了不虧。將他們運(yùn)用在一些高頻事件的優(yōu)化上能有很大的性能提升。
1. 防抖(debounce)
在事件被觸發(fā)n秒后再執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計時。
常用于監(jiān)聽keyup等,比如在實(shí)現(xiàn)一個根據(jù)輸入字會動態(tài)顯示在下方的搜索內(nèi)容的輸入框,如果不使用防抖的話,每次keyup或者change時都會進(jìn)行一次請求,會對服務(wù)器造成很大的壓力。
先來看一下最簡單的實(shí)現(xiàn)代碼:
上面的方法存在兩個問題
timer暴露在外,會對全局造成污染
fn如果要傳參需要在debounce那里傳入,雖然可以使用arguments,但不是很好。
那么針對以上的問題完善后:
在外層使用函數(shù)包起來解決全局污染問題,同時使用第二層函數(shù)傳參,解決函數(shù)傳參問題。
最后再優(yōu)化下第一次調(diào)用無法立即執(zhí)行的問題
2. 節(jié)流(throttle)
每隔一段時間,只執(zhí)行一次函數(shù)。
我個人比較喜歡在監(jiān)聽resize時使用。
如果使用的是rem等,那就會導(dǎo)致瀏覽器一直在重繪,會造成很大消耗。在使用throttle后在一段時間內(nèi)只執(zhí)行一次,將N次變?yōu)橐粌纱危艽蟮臏p少了瀏覽器損耗。但常規(guī)的話是用在按鈕重復(fù)點(diǎn)擊的情況下,保證一段時間內(nèi)重復(fù)點(diǎn)擊按鈕只會觸發(fā)一次并且不是最后一次點(diǎn)擊等。
來看下的實(shí)現(xiàn)方法(常見的是使用時間戳,所以這里不會展示使用定時器的節(jié)流):
優(yōu)化下,讓監(jiān)聽停止后最后一次執(zhí)行,使用定時器做最后一次延遲執(zhí)行。
不足之處,麻煩指出,謝謝!