摘要:函數(shù)節(jié)流指定時(shí)間間隔內(nèi)只會(huì)執(zhí)行一次任務(wù)函數(shù)防抖任務(wù)頻繁觸發(fā)的情況下,只有任務(wù)觸發(fā)的間隔超過(guò)指定間隔的時(shí)候,任務(wù)才會(huì)執(zhí)行。使用函數(shù)節(jié)流與函數(shù)防抖的目的,在開(kāi)頭的栗子中應(yīng)該也能看得出來(lái),就是為了節(jié)約計(jì)算機(jī)資源。
什么是函數(shù)節(jié)流與函數(shù)防抖
舉個(gè)栗子,我們知道目前的一種說(shuō)法是當(dāng) 1 秒內(nèi)連續(xù)播放 24 張以上的圖片時(shí),在人眼的視覺(jué)中就會(huì)形成一個(gè)連貫的動(dòng)畫(huà),所以在電影的播放(以前是,現(xiàn)在不知道)中基本是以每秒 24 張的速度播放的,為什么不 100 張或更多是因?yàn)?24 張就可以滿足人類(lèi)視覺(jué)需求的時(shí)候,100 張就會(huì)顯得很浪費(fèi)資源。再舉個(gè)栗子,假設(shè)電梯一次只能載一人的話,10 個(gè)人要上樓的話電梯就得走 10 次,是一種浪費(fèi)資源的行為;而實(shí)際生活正顯然不是這樣的,當(dāng)電梯里有人準(zhǔn)備上樓的時(shí)候如果外面又有人按電梯的話,電梯會(huì)再次打開(kāi)直到滿載位置,從電梯的角度來(lái)說(shuō),這時(shí)一種節(jié)約資源的行為(相對(duì)于一次只能載一個(gè)人)。
函數(shù)節(jié)流: 指定時(shí)間間隔內(nèi)只會(huì)執(zhí)行一次任務(wù);
函數(shù)防抖: 任務(wù)頻繁觸發(fā)的情況下,只有任務(wù)觸發(fā)的間隔超過(guò)指定間隔的時(shí)候,任務(wù)才會(huì)執(zhí)行。
函數(shù)節(jié)流(throttle)這里以判斷頁(yè)面是否滾動(dòng)到底部為例,普通的做法就是監(jiān)聽(tīng) window 對(duì)象的 scroll 事件,然后再函數(shù)體中寫(xiě)入判斷是否滾動(dòng)到底部的邏輯:
function onScroll() { // 判斷是否滾動(dòng)到底部的邏輯 const pageHeight = $("body").height(); const scrollTop = $(window).scrollTop(); const winHeight = $(window).height(); const thresold = pageHeight - scrollTop - winHeight; if (thresold > -100 && thresold <= 20) { console.log("end"); } } $(window).on("scroll", onScroll);
這樣做的一個(gè)缺點(diǎn)就是比較消耗性能,因?yàn)楫?dāng)在滾動(dòng)的時(shí)候,瀏覽器會(huì)無(wú)時(shí)不刻地在計(jì)算判斷是否滾動(dòng)到底部的邏輯,而在實(shí)際的場(chǎng)景中是不需要這么做的,在實(shí)際場(chǎng)景中可能是這樣的:在滾動(dòng)過(guò)程中,每隔一段時(shí)間在去計(jì)算這個(gè)判斷邏輯。而函數(shù)節(jié)流所做的工作就是每隔一段時(shí)間去執(zhí)行一次原本需要無(wú)時(shí)不刻地在執(zhí)行的函數(shù),所以在滾動(dòng)事件中引入函數(shù)的節(jié)流是一個(gè)非常好的實(shí)踐:
$(window).on("scroll", throttle(onScroll));
加上函數(shù)節(jié)流之后,當(dāng)頁(yè)面再滾動(dòng)的時(shí)候,每隔 300ms 才會(huì)去執(zhí)行一次判斷邏輯。
簡(jiǎn)單來(lái)說(shuō),函數(shù)的節(jié)流就是通過(guò)閉包保存一個(gè)標(biāo)記(canRun = true),在函數(shù)的開(kāi)頭判斷這個(gè)標(biāo)記是否為 true,如果為 true 的話就繼續(xù)執(zhí)行函數(shù),否則則 return 掉,判斷完標(biāo)記后立即把這個(gè)標(biāo)記設(shè)為 false,然后把外部傳入的函數(shù)的執(zhí)行包在一個(gè) setTimeout 中,最后在 setTimeout 執(zhí)行完畢后再把標(biāo)記設(shè)置為 true(這里很關(guān)鍵),表示可以執(zhí)行下一次的循環(huán)了。當(dāng) setTimeout 還未執(zhí)行的時(shí)候,canRun 這個(gè)標(biāo)記始終為 false,在開(kāi)頭的判斷中被 return 掉。
function throttle(fn, interval = 300) { let canRun = true; return function () { if (!canRun) return; canRun = false; setTimeout(() => { fn.apply(this, arguments); canRun = true; }, interval); }; }函數(shù)防抖(debounce)
這里以用戶注冊(cè)時(shí)驗(yàn)證用戶名是否被占用為例,如今很多網(wǎng)站為了提高用戶體驗(yàn),不會(huì)再輸入框失去焦點(diǎn)的時(shí)候再去判斷用戶名是否被占用,而是在輸入的時(shí)候就在判斷這個(gè)用戶名是否已被注冊(cè):
$("input.user-name").on("input", function () { $.ajax({ url: `https://just.com/check`, method: "post", data: { username: $(this).val(), }, success(data) { if (data.isRegistered) { $(".tips").text("該用戶名已被注冊(cè)!"); } else { $(".tips").text("恭喜!該用戶名還未被注冊(cè)!"); } }, error(error) { console.log(error); }, }); });
很明顯,這樣的做法不好的是當(dāng)用戶輸入第一個(gè)字符的時(shí)候,就開(kāi)始請(qǐng)求判斷了,不僅對(duì)服務(wù)器的壓力增大了,對(duì)用戶體驗(yàn)也未必比原來(lái)的好。而理想的做法應(yīng)該是這樣的,當(dāng)用戶輸入第一個(gè)字符后的一段時(shí)間內(nèi)如果還有字符輸入的話,那就暫時(shí)不去請(qǐng)求判斷用戶名是否被占用。在這里引入函數(shù)防抖就能很好地解決這個(gè)問(wèn)題:
$("input.user-name").on("input", debounce(function () { $.ajax({ url: `https://just.com/check`, method: "post", data: { username: $(this).val(), }, success(data) { if (data.isRegistered) { $(".tips").text("該用戶名已被注冊(cè)!"); } else { $(".tips").text("恭喜!該用戶名還未被注冊(cè)!"); } }, error(error) { console.log(error); }, }); }));
其實(shí)函數(shù)防抖的原理也非常地簡(jiǎn)單,通過(guò)閉包保存一個(gè)標(biāo)記來(lái)保存 setTimeout 返回的值,每當(dāng)用戶輸入的時(shí)候把前一個(gè) setTimeout clear 掉,然后又創(chuàng)建一個(gè)新的 setTimeout,這樣就能保證輸入字符后的 interval 間隔內(nèi)如果還有字符輸入的話,就不會(huì)執(zhí)行 fn 函數(shù)了。
function debounce(fn, interval = 300) { let timeout = null; return function () { clearTimeout(timeout); timeout = setTimeout(() => { fn.apply(this, arguments); }, interval); }; }總結(jié)
其實(shí)函數(shù)節(jié)流與函數(shù)防抖的原理非常簡(jiǎn)單,巧妙地使用 setTimeout 來(lái)存放待執(zhí)行的函數(shù),這樣可以很方便的利用 clearTimeout 在合適的時(shí)機(jī)來(lái)清除待執(zhí)行的函數(shù)。
使用函數(shù)節(jié)流與函數(shù)防抖的目的,在開(kāi)頭的栗子中應(yīng)該也能看得出來(lái),就是為了節(jié)約計(jì)算機(jī)資源。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/100654.html
摘要:若時(shí)間差大于間隔時(shí)間,則立刻執(zhí)行一次函數(shù)。不同點(diǎn)函數(shù)防抖,在一段連續(xù)操作結(jié)束后,處理回調(diào),利用和實(shí)現(xiàn)。函數(shù)防抖關(guān)注一定時(shí)間連續(xù)觸發(fā)的事件只在最后執(zhí)行一次,而函數(shù)節(jié)流側(cè)重于一段時(shí)間內(nèi)只執(zhí)行一次。 原博客地址,歡迎star 函數(shù)防抖和節(jié)流 函數(shù)防抖和函數(shù)節(jié)流:優(yōu)化高頻率執(zhí)行js代碼的一種手段,js中的一些事件如瀏覽器的resize、scroll,鼠標(biāo)的mousemove、mouseover...
摘要:隆重請(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),不少伙伴們還...
摘要:基礎(chǔ)防抖我們現(xiàn)在寫(xiě)一個(gè)最基礎(chǔ)的防抖處理標(biāo)記事件也做如下改寫(xiě)現(xiàn)在試一下,我們會(huì)發(fā)現(xiàn)只有我們停止?jié)L動(dòng)秒鐘的時(shí)候,控制臺(tái)才會(huì)打印出一行隨機(jī)數(shù)。 為何要防抖和節(jié)流 有時(shí)候會(huì)在項(xiàng)目開(kāi)發(fā)中頻繁地觸發(fā)一些事件,如 resize、 scroll、 keyup、 keydown等,或者諸如輸入框的實(shí)時(shí)搜索功能,我們知道如果事件處理函數(shù)無(wú)限制調(diào)用,會(huì)大大加重瀏覽器的工作量,有可能導(dǎo)致頁(yè)面卡頓影響體驗(yàn);后臺(tá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ì)持...
摘要:函數(shù)防抖簡(jiǎn)單實(shí)現(xiàn)模擬請(qǐng)求獲取函數(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) 名詞解釋?zhuān)涸谑录挥|發(fā)n秒后再執(zhí)行回調(diào)函數(shù),如果在這n秒內(nèi)又被觸發(fā),則重新計(jì)時(shí)。 使用場(chǎng)景:以百度輸入框例,比如你要查詢...
閱讀 2014·2021-10-12 10:12
閱讀 3137·2019-08-30 15:44
閱讀 897·2019-08-30 15:43
閱讀 3060·2019-08-30 14:02
閱讀 2158·2019-08-30 12:54
閱讀 3568·2019-08-26 17:05
閱讀 2056·2019-08-26 13:34
閱讀 1108·2019-08-26 11:54