為什么要使用防抖和節(jié)流
? ? ? ? 防抖和節(jié)流主要用于需要進行連續(xù)的時間監(jiān)聽上面,比如resize,scroll,mousemove等等锰悼,但是對于我們來說谢鹊,不希望事件持續(xù)的觸發(fā)過程中去頻繁的去執(zhí)行回調函數镜硕。如果這些回調函數包含一些向后端發(fā)起的請求闻妓,比如監(jiān)聽input輸入框中的內容向后端發(fā)起ajax請求,那么在持續(xù)輸入信息時會不斷向后端發(fā)起請求渗常,這樣不僅從資源上來說是很浪費的行為壮不,而且實際應用中,用戶也是輸出完整的字符后皱碘,才會請求
防抖
? ? ? ? 防抖是指停止觸發(fā)事件后在等待n秒執(zhí)行一次询一,如果在n秒內又觸發(fā)了事件,那么就會重新刷新n秒時間
? ? ? ? 1癌椿、例子:比如說坐公交健蕊,每一位乘客上車代表觸發(fā)一次事件,當最后一個乘客上車后踢俄,司機等待幾秒后才關門绊诲。
? ? ? ? 2、前端中應用場景:
? ? ? ? ? ? ? ?*搜索框中搜索輸入褪贵,只需用戶最后一次輸入完,在發(fā)起請求
? ? ? ? ? ? ? ?*手機號抗俄,郵箱驗證
? ? ? ? 3脆丁、防抖函數分為立即執(zhí)行版和非立即執(zhí)行版
? ? ? ? ? ? ? 非立即執(zhí)行版
? ? ? ? ? ? 代碼思想:該代碼的運行原理是,通過監(jiān)聽div當鼠標每次移動時都會執(zhí)行debounce函數返回的那個函數(debounce函數只執(zhí)行一次)动雹,每次移動都會導致回調函數中的計時器重新開始計時槽卫,當計時開始滿足1s后才執(zhí)行回調函數(先等待滿足一秒后執(zhí)行)。
疑問一:
? ? ? ? ? ? 這里有很多人也許不知道變量context和args在這里的作用胰蝠,那么可以對比addEventListener進行的事件監(jiān)聽歼培,在addEventListener的監(jiān)聽中我們可以向回調函數傳和參數e震蒋,這個e和這里的args是等價的。而這個this是為了保持指向不變
疑問二:
? ? ? ? ? 變量timeout每次函數執(zhí)行完躲庄,不會消失嗎查剖。這里就涉及的閉包,不熟悉閉包的可以先學習學習閉包噪窘。當該函數debounce(Fun,?1000)執(zhí)行時就會產生一個閉包笋庄,當debounce函數執(zhí)行完時,timeout依然存在于內存中倔监,我們可以通過對div的監(jiān)聽來執(zhí)行debounce返回的函數直砂,并修改timerout中的數值。注意在該代碼的運行中只產生了一個閉包浩习。
? ? ? ? ? ? ? ? 立即執(zhí)行版
? ? ? 代碼思想:該代碼是通過控制timeout的值來確定是否執(zhí)行回調函數静暂,如果timeout的值為? ? ? ? ?false那么將會立即執(zhí)行func.apply()否則將不會執(zhí)行函數。當首次事件觸發(fā)時(timeout==false)谱秽,會立即執(zhí)行函數洽蛀,如果在此階段不斷的觸發(fā)事件(timeout==true)那么定時器會不斷清除,直到等待一秒內部觸發(fā)弯院,
該代碼在定時器中修改timeout的值辱士,如果在等待的時間內重新觸發(fā)事件,那么原來的定時器會被清除听绳,重新開始計時颂碘,知道滿足1s后再執(zhí)行(先執(zhí)行函數后等待時間)
節(jié)流
? ? ? ? 連續(xù)觸發(fā)事件但是函數在n秒鐘只執(zhí)行一次
? ? ? ? ? 1、例子:乘坐地鐵椅挣,過閘機時头岔,每個人進入后3秒后門關閉,等待下一個人進入鼠证。
? ? ? ? ? 2峡竣、前端應用場景:
? ? ? ? ? ? ? ? ?*滾動加載,加載更多或滾動到底部監(jiān)聽
? ? ? ? ? ? ? ? ?*高頻點擊提交量九,表單重復提交
? ? ? ? ? 3适掰、節(jié)流分為時間戳版和定時器版
? ? ? ? ? ? ? ? 事件戳版
? ? ? ? ? ? ? ? ? ?定時器版