摘要:封裝方法也比較簡單,書中對此問題也進(jìn)行了處理使用定時(shí)器,讓函數(shù)延遲秒后執(zhí)行,在此秒內(nèi),然后函數(shù)再次被調(diào)用,則刪除上次的定時(shí)器,取消上次調(diào)用的隊(duì)列任務(wù),重新設(shè)置定時(shí)器。
在實(shí)際開發(fā)中,函數(shù)一定是最實(shí)用最頻繁的一部分,無論是以函數(shù)為核心的函數(shù)式編程,還是更多人選擇的面向?qū)ο笫降木幊?,都?huì)有函數(shù)的身影,所以對函數(shù)進(jìn)行深入的研究是非常有必要的。
函數(shù)節(jié)流比較直白的說,函數(shù)節(jié)流就是強(qiáng)制規(guī)定一個(gè)函數(shù)在一段時(shí)間內(nèi)能夠被執(zhí)行的最大次數(shù),比如,規(guī)定某個(gè)函數(shù)在每100毫秒的時(shí)間段內(nèi),最多被執(zhí)行一次,那么對應(yīng)的在10s(10000ms)內(nèi),最多就會(huì)執(zhí)行100(10000ms/100ms)次
這里節(jié)流和防抖的概念比較容易搞混,所以文中許多關(guān)鍵性定義,參考此處文檔翻譯過來,移步到the-difference-between-throttling-and-debouncing
在瀏覽器中,頻繁的DOM操作非常消耗內(nèi)存和CPU時(shí)間,比如監(jiān)聽了resize,touchmove,scroll...等事件,在dom改變時(shí)都會(huì)不斷觸發(fā)回調(diào)?,F(xiàn)在的react 和 vue 等前端框架都提出了虛擬DOM的概念,會(huì)把多次DOM操作合并到一次真實(shí)操作中,就是使用了Diff算法,這樣就大大減低了DOM操作的頻次。但是,這里并不是要討論diff算法,如果感興趣可以戳上面的鏈接,而是解釋如何利用setTimeout來減低DOM頻繁操作的風(fēng)險(xiǎn)。
最早接觸到這個(gè)概念的時(shí)候,是在《高程3》最后幾章上面。
函數(shù)節(jié)流背后的基本思想是指,某些代碼不可以在沒有間斷的情況下連續(xù)重復(fù)執(zhí)行.第一次調(diào)用函數(shù),創(chuàng)建了一個(gè)定時(shí)器,在指定的時(shí)間間隔之后運(yùn)行代碼。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器并設(shè)置另一個(gè)。
封裝方法也比較簡單,書中對此問題也進(jìn)行了處理:
function throttle(method,context) { clearTimeout(method.tId); method.tId = setTimeout(function(){ method.call(context) },1000) }
使用定時(shí)器,讓函數(shù)延遲1秒后執(zhí)行,在此1秒內(nèi),然后throttle函數(shù)再次被調(diào)用,則刪除上次的定時(shí)器,取消上次調(diào)用的隊(duì)列任務(wù),重新設(shè)置定時(shí)器。這樣就可以保證1秒內(nèi)函數(shù)只會(huì)被觸發(fā)一次,達(dá)到了函數(shù)節(jié)流的目的
可以利用 resize事件測試一下;
var i = 0; function handler(){ console.log(i++); } window.onresize = function(){ throttle(handler,window) }
可以發(fā)現(xiàn),在瀏覽器的調(diào)試模式下,切換橫屏/豎屏,只觸發(fā)了一次
函數(shù)防抖函數(shù)防抖 規(guī)定函數(shù)再次執(zhí)行需要滿足兩個(gè)條件:
1,必須要等待一段時(shí)間;
2,在條件1等待的時(shí)間段內(nèi)不再被觸發(fā),一旦在條件1等待的時(shí)間內(nèi)再次被觸發(fā),等待時(shí)間就要重新開始計(jì)算。
比如:對一個(gè)函數(shù)加了100ms的防抖操作,然后在3s(3000ms)時(shí)間段內(nèi),這個(gè)函數(shù)被不連續(xù)的調(diào)用了1000次,3s后停止調(diào)用。 它只會(huì)在3100ms的時(shí)刻執(zhí)行一次。
具體實(shí)現(xiàn)代碼,看下 underscore.js中的 _.debounce 源碼:
// Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. _.debounce = function(func, wait, immediate) { var timeout, args, context, timestamp, result; var later = function() { var last = _.now() - timestamp; if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) { result = func.apply(context, args); if (!timeout) context = args = null; } } }; return function() { context = this; args = arguments; timestamp = _.now(); var callNow = immediate && !timeout; if (!timeout) timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); context = args = null; } return result; }; };
wait參數(shù)代表debounce時(shí)間, _.now()返回當(dāng)前時(shí)間的時(shí)間戳,同樣以ms 為單位。 如果傳入了 immediate,會(huì)立即觸發(fā)回調(diào)函數(shù)。
應(yīng)用場景:
在使用高德地址聯(lián)想輸入提示時(shí),只有在用戶停止鍵盤輸入時(shí),才去進(jìn)行ajax請求
elementUI inputNumber計(jì)算器組件中,為了防止用戶多次點(diǎn)擊,數(shù)字自動(dòng)增減,也使用了防抖操作,有興趣可以查看源碼
參考資料:
the-difference-between-throttling-and-debouncing
淺談javascript的函數(shù)節(jié)流(騰訊全端 AlloyTeam 團(tuán)隊(duì) Blog)
JavaScript 函數(shù)節(jié)流
函數(shù)防抖與節(jié)流
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/92254.html
摘要:文章來源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學(xué)問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...
摘要:文章來源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學(xué)問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...
摘要:函數(shù)防抖簡單實(shí)現(xiàn)模擬請求獲取函數(shù)的作用域和變量清除定時(shí)器節(jié)流名詞解釋連續(xù)執(zhí)行函數(shù),每隔一定時(shí)間執(zhí)行函數(shù)。效果函數(shù)防抖是某一段時(shí)間內(nèi)只執(zhí)行一次函數(shù)節(jié)流是間隔時(shí)間執(zhí)行,不管事件觸發(fā)有多頻繁,都會(huì)保證在規(guī)定時(shí)間內(nèi)一定會(huì)執(zhí)行一次真正的事件處理函數(shù)。 防抖(debounce) 名詞解釋:在事件被觸發(fā)n秒后再執(zhí)行回調(diào)函數(shù),如果在這n秒內(nèi)又被觸發(fā),則重新計(jì)時(shí)。 使用場景:以百度輸入框例,比如你要查詢...
摘要:隆重請出主角防抖與節(jié)流。防抖與節(jié)流的異同相同都是防止某一時(shí)間段內(nèi),函數(shù)被頻繁調(diào)用執(zhí)行,通過時(shí)間頻率控制,減少回調(diào)函數(shù)執(zhí)行次數(shù),來實(shí)現(xiàn)相關(guān)性能優(yōu)化。參考文章分鐘理解的節(jié)流防抖及使用場景函數(shù)防抖和節(jié)流 showImg(https://segmentfault.com/img/bVburM8?w=800&h=600); 本篇課題,或許早已是爛大街的解讀文章。不過春招系列面試下來,不少伙伴們還...
摘要:防抖與節(jié)流源碼學(xué)習(xí)最近自己擼了一個(gè)輪播圖,在點(diǎn)擊切換的時(shí)候,為了尋求更好的用戶體驗(yàn),引入了節(jié)流,在此記錄對源碼的學(xué)習(xí)過程源碼來源防抖函數(shù)防抖使用場景現(xiàn)在我們需要做一個(gè)搜索框,當(dāng)用戶輸入文字,執(zhí)行事件的時(shí)候,需要發(fā)出異步請求去進(jìn)行結(jié)果查詢。 防抖與節(jié)流(源碼學(xué)習(xí)) 最近自己擼了一個(gè)輪播圖,在點(diǎn)擊切換的時(shí)候,為了尋求更好的用戶體驗(yàn),引入了節(jié)流,在此記錄對源碼的學(xué)習(xí)過程源碼來源:unders...
閱讀 3807·2021-11-12 10:34
閱讀 2822·2021-09-22 15:14
閱讀 790·2019-08-30 15:53
閱讀 3207·2019-08-30 12:53
閱讀 1290·2019-08-29 18:32
閱讀 2771·2019-08-29 16:41
閱讀 1068·2019-08-26 13:40
閱讀 1810·2019-08-23 18:07