摘要:防抖與節(jié)流源碼學(xué)習(xí)最近自己擼了一個(gè)輪播圖,在點(diǎn)擊切換的時(shí)候,為了尋求更好的用戶體驗(yàn),引入了節(jié)流,在此記錄對(duì)源碼的學(xué)習(xí)過(guò)程源碼來(lái)源防抖函數(shù)防抖使用場(chǎng)景現(xiàn)在我們需要做一個(gè)搜索框,當(dāng)用戶輸入文字,執(zhí)行事件的時(shí)候,需要發(fā)出異步請(qǐng)求去進(jìn)行結(jié)果查詢(xún)。
防抖與節(jié)流(源碼學(xué)習(xí))
最近自己擼了一個(gè)輪播圖,在點(diǎn)擊切換的時(shí)候,為了尋求更好的用戶體驗(yàn),引入了節(jié)流,在此記錄對(duì)源碼的學(xué)習(xí)過(guò)程
源碼來(lái)源:underscore
函數(shù)防抖(debounce)
使用場(chǎng)景:現(xiàn)在我們需要做一個(gè)搜索框,當(dāng)用戶輸入文字,執(zhí)行keyup事件的時(shí)候,需要發(fā)出異步請(qǐng)求去進(jìn)行結(jié)果查詢(xún)。但如果用戶快速輸入了一連串字符,例如是5個(gè)字符,那么此時(shí)會(huì)瞬間觸發(fā)5次請(qǐng)求,這肯定不是我們希望的結(jié)果。我們想要的是用戶停止輸入的時(shí)候才去觸發(fā)查詢(xún)的請(qǐng)求,這個(gè)時(shí)候函數(shù)防抖可以幫到我們
原理:讓函數(shù)在上次執(zhí)行后,滿足等待某個(gè)時(shí)間內(nèi)不再觸發(fā)次函數(shù)后再執(zhí)行,如果觸發(fā)則等待時(shí)間重新計(jì)算
function debounce (func, wait, immediate) { var timeout, result; var later = function (context, args) { timeout = null;//重置 if (args) result = func.apply(context, args); }; var debounced = restArguments(function (args) { if (timeout) clearTimeout(timeout);//如果觸發(fā)則等待時(shí)間重新計(jì)算 if (immediate) {//應(yīng)用場(chǎng)景,比如提交表單,需要立即執(zhí)行一次 var callNow = !timeout;//是否為第一次觸發(fā),如果是第一次觸發(fā),timeout是undefined timeout = setTimeout(later, wait);//注意,這里沒(méi)有args,僅僅只是在wait毫秒后重置清空timeout, if (callNow) result = func.apply(this, args);//如果是immediate且是第一次觸發(fā),立即執(zhí)行一次;result為立即執(zhí)行的結(jié)果,這里this直接綁定到用戶的func } else { timeout = delay(later, wait, this, args);//settimeout,注意:這里的this通過(guò)參數(shù)傳給later綁定到func } return result; }); //重置,取消執(zhí)行 debounced.cancel = function () { clearTimeout(timeout); timeout = null; }; return debounced; };節(jié)流
函數(shù)節(jié)流(throttle)
使用場(chǎng)景:window.onscroll,以及window.onresize等,每間隔某個(gè)時(shí)間去執(zhí)行某函數(shù),避免函數(shù)的過(guò)多執(zhí)行
原理:與函數(shù)防抖不同,它不是要在每完成某個(gè)等待時(shí)間后去執(zhí)行某個(gè)函數(shù),而是要每間隔某個(gè)時(shí)間去執(zhí)行某個(gè)函數(shù)
// leading:是否立即執(zhí)行 // trailing: true // wait期間如果再次調(diào)用,是否會(huì)在周期后邊緣(wait剛結(jié)束)再次執(zhí)行 //leading = true;trailing = true; 調(diào)用立即執(zhí)行一次,wait期間如果再次調(diào)用,會(huì)在周期后邊緣(wait剛結(jié)束)再次執(zhí)行 //leading = true;trailing = false; 調(diào)用立即執(zhí)行一次,wait期間如果再次調(diào)用,什么也不做 //leading = false;trailing = true; 調(diào)用需等待wait時(shí)間,wait期間如果再次調(diào)用,會(huì)在周期后邊緣(wait剛結(jié)束)執(zhí)行 //leading = false;trailing = false; 調(diào)用需等待wait時(shí)間,wait期間如果再次調(diào)用,什么也不做 function throttle (func, wait, options) { var timeout, context, args, result; var previous = 0;//上次執(zhí)行時(shí)間 if (!options) options = {}; var later = function () { previous = options.leading === false ? 0 : _.now();//設(shè)置為0的話下次調(diào)用會(huì)立即執(zhí)行 timeout = null; result = func.apply(context, args);//可能設(shè)置timeout? if (!timeout) context = args = null; }; var throttled = function () { var now = _.now(); if (!previous && options.leading === false) previous = now;//如果不是立即執(zhí)行 var remaining = wait - (now - previous);//剩余時(shí)間 context = this; args = arguments; if (remaining <= 0 || remaining > wait) {//開(kāi)始執(zhí)行 if (timeout) { clearTimeout(timeout); timeout = null; } previous = now;//記錄執(zhí)行時(shí)間 result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining);//注意只有這個(gè)地方對(duì)timeout賦值了且調(diào)用了later } return result; }; //取消 throttled.cancel = function () { clearTimeout(timeout); previous = 0; timeout = context = args = null; }; return throttled; };總結(jié)
所有學(xué)習(xí)過(guò)程可見(jiàn)注釋?zhuān)暾⑨孏itHub地址
其中我在造輪播圖的輪子的過(guò)程中,引入了節(jié)流來(lái)優(yōu)化用戶主動(dòng)點(diǎn)擊切換,一次來(lái)提升用戶體驗(yàn),感覺(jué)上還是好很多的。
輪播圖演示地址
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94959.html
摘要:封裝方法也比較簡(jiǎn)單,書(shū)中對(duì)此問(wèn)題也進(jìn)行了處理使用定時(shí)器,讓函數(shù)延遲秒后執(zhí)行,在此秒內(nèi),然后函數(shù)再次被調(diào)用,則刪除上次的定時(shí)器,取消上次調(diào)用的隊(duì)列任務(wù),重新設(shè)置定時(shí)器。 在實(shí)際開(kāi)發(fā)中,函數(shù)一定是最實(shí)用最頻繁的一部分,無(wú)論是以函數(shù)為核心的函數(shù)式編程,還是更多人選擇的面向?qū)ο笫降木幊?,都?huì)有函數(shù)的身影,所以對(duì)函數(shù)進(jìn)行深入的研究是非常有必要的。 函數(shù)節(jié)流 比較直白的說(shuō),函數(shù)節(jié)流就是強(qiáng)制規(guī)定一...
摘要:譯通過(guò)實(shí)例講解和防抖與節(jié)流源碼中推薦的文章,為了學(xué)習(xí)英語(yǔ),翻譯了一下原文鏈接作者本文來(lái)自一位倫敦前端工程師的技術(shù)投稿。首次或立即你可能發(fā)現(xiàn)防抖事件在等待觸發(fā)事件執(zhí)行,直到事件都結(jié)束后它才執(zhí)行。 [譯]通過(guò)實(shí)例講解Debouncing和Throtting(防抖與節(jié)流) lodash源碼中推薦的文章,為了學(xué)習(xí)(英語(yǔ)),翻譯了一下~ 原文鏈接 作者:DAVID CORBACHO 本文來(lái)自一位...
摘要:隆重請(qǐng)出主角防抖與節(jié)流。防抖與節(jié)流的異同相同都是防止某一時(shí)間段內(nèi),函數(shù)被頻繁調(diào)用執(zhí)行,通過(guò)時(shí)間頻率控制,減少回調(diào)函數(shù)執(zhí)行次數(shù),來(lái)實(shí)現(xiàn)相關(guān)性能優(yōu)化。參考文章分鐘理解的節(jié)流防抖及使用場(chǎng)景函數(shù)防抖和節(jié)流 showImg(https://segmentfault.com/img/bVburM8?w=800&h=600); 本篇課題,或許早已是爛大街的解讀文章。不過(guò)春招系列面試下來(lái),不少伙伴們還...
摘要:文章來(lái)源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書(shū)示子聿》——古人學(xué)問(wèn)無(wú)遺力,少壯工夫老始成。紙上得來(lái)終覺(jué)淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩(shī)的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開(kāi)發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...
摘要:文章來(lái)源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書(shū)示子聿》——古人學(xué)問(wèn)無(wú)遺力,少壯工夫老始成。紙上得來(lái)終覺(jué)淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩(shī)的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開(kāi)發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...
閱讀 2055·2021-11-15 11:39
閱讀 3237·2021-10-09 09:41
閱讀 1501·2019-08-30 14:20
閱讀 3274·2019-08-30 13:53
閱讀 3334·2019-08-29 16:32
閱讀 3394·2019-08-29 11:20
閱讀 3032·2019-08-26 13:53
閱讀 783·2019-08-26 12:18