最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS函數(shù)節(jié)流和防抖之間的區(qū)分和實(shí)現(xiàn)詳解

 更新時(shí)間:2019年01月11日 09:48:39   作者:前端開發(fā)博客  
本文主要介紹的是關(guān)于JS中比較常用的函數(shù):節(jié)流函數(shù)和防抖函數(shù),從概念、使用場景到代碼簡單實(shí)現(xiàn)做了一個(gè)詳細(xì)的區(qū)分。感興趣的小伙伴們可以參考一下

在寫JS時(shí),這兩個(gè)函數(shù)比較常見,有時(shí)候傻傻分不清用哪個(gè),或者說知道代碼要怎么寫,但要說出它究竟是節(jié)流函數(shù)還是防抖函數(shù)時(shí)一臉楞逼。今天有一個(gè)同學(xué)分享了這兩個(gè)的區(qū)分,我也來回顧一下,加深一下印象,以便日后用到時(shí)心里有底。PS:百度和谷歌搜索前幾個(gè)介紹都是相反介紹,本文為原創(chuàng),如有雷同純屬抄襲我的。

節(jié)流概念(Throttle)

按照設(shè)定的時(shí)間固定執(zhí)行一次函數(shù),比如200ms一次。注意:固定就是你在mousemove過程中,執(zhí)行這個(gè)節(jié)流函數(shù),它一定是200ms(你設(shè)定的定時(shí)器延遲時(shí)間)內(nèi)執(zhí)行一次。沒到200ms,一定會(huì)返回,沒有執(zhí)行回調(diào)函數(shù)的。

主要應(yīng)用場景有:scroll、touchmove

防抖概念(Debounce)

抖動(dòng)停止后的時(shí)間超過設(shè)定的時(shí)間時(shí)執(zhí)行一次函數(shù)。注意:這里的抖動(dòng)停止表示你停止了觸發(fā)這個(gè)函數(shù),從這個(gè)時(shí)間點(diǎn)開始計(jì)算,當(dāng)間隔時(shí)間等于你設(shè)定時(shí)間,才會(huì)執(zhí)行里面的回調(diào)函數(shù)。如果你一直在觸發(fā)這個(gè)函數(shù)并且兩次觸發(fā)間隔小于設(shè)定時(shí)間,則一定不會(huì)到回調(diào)函數(shù)那一步。

主要應(yīng)用場景有:input驗(yàn)證、搜索聯(lián)想、resize

節(jié)流實(shí)現(xiàn)

思路: 第一次先設(shè)定一個(gè)變量true,第二次執(zhí)行這個(gè)函數(shù)時(shí),會(huì)判斷變量是否true,是則返回。當(dāng)?shù)谝淮蔚亩〞r(shí)器執(zhí)行完函數(shù)最后會(huì)設(shè)定變量為flase。那么下次判斷變量時(shí)則為flase,函數(shù)會(huì)依次運(yùn)行。

代碼一:首次不執(zhí)行

function throttle(fn,delay=100){
 //首先設(shè)定一個(gè)變量,在沒有執(zhí)行我們的定時(shí)器時(shí)為null
 let timer = null;
 return function(){
 //當(dāng)我們發(fā)現(xiàn)這個(gè)定時(shí)器存在時(shí),則表示定時(shí)器已經(jīng)在運(yùn)行中,需要返回
 if(timer) return;
 timer = setTimeout(()=>{
 fn.apply(this,arguments);
 timer = null;
 },delay);
 }
}

代碼二:首次執(zhí)行

function throttle2(fn,delay=100){
 let last = 0;
 return function(){
 let curr = +new Date();
 if(curr - last > delay){
 fn.apply(this,arguments);
 last = curr;
 }
 }
}

防抖實(shí)現(xiàn)

思路:首次運(yùn)行時(shí)把定時(shí)器賦值給一個(gè)變量,第二次執(zhí)行時(shí),如果間隔沒超過定時(shí)器設(shè)定的時(shí)間則會(huì)清除掉定時(shí)器,重新設(shè)定定時(shí)器,依次反復(fù),當(dāng)我們停止下來時(shí),沒有執(zhí)行清除定時(shí)器,超過一定時(shí)間后觸發(fā)回調(diào)函數(shù)。

代碼一:首次不執(zhí)行

function debounce(fn,delay=200){
 let timer = null;
 return function(){
 if(timer) clearTimeout(timer);
 timer = setTimeout(()=>{
 fn.apply(this,arguments);
 timer = null;
 },delay);
 }
}

代碼二:首次執(zhí)行

function debounce2(fn, delay = 200, atBegin = true) {
 let timer = null, last = 0,during;
 return function () {
 let self = this, args = arguments;
 var exec = function () {
 fn.apply(self, args);
 }
 if (atBegin && !timer) {
 exec();
 atBegin = false;
 } else {
 during = Date.now() - last;
 if (during > delay) {
 exec();
 } else {
 if (timer) clearTimeout(timer);
 timer = setTimeout(function () {
  exec();
 }, delay);
 }
 }
 last = Date.now();
 }
}

上面的代碼只是我自己的一個(gè)簡單實(shí)現(xiàn),看看lodash里面的兩個(gè)核心實(shí)現(xiàn)代碼。生產(chǎn)中建議使用它們的庫,畢竟有這么多人在用,出bug的機(jī)會(huì)比較少,我上面的代碼有可能有一些情況沒考慮到。如果你發(fā)現(xiàn)有問題的,也請(qǐng)告訴我。

如果在項(xiàng)目中有需要用到的,可以直接安裝單個(gè)的NPM模塊。throttle 和 debounce

lodash使用使用文檔

lodash庫里面這兩個(gè)函數(shù)設(shè)置的參數(shù)有點(diǎn)復(fù)雜,記錄一下里面的參數(shù)和代碼使用。

節(jié)流(throttle)

官方文檔解釋:

創(chuàng)建一個(gè)節(jié)流函數(shù),在 wait 秒內(nèi)最多執(zhí)行 func 一次的函數(shù)。 該函數(shù)提供一個(gè) cancel 方法取消延遲的函數(shù)調(diào)用以及 flush 方法立即調(diào)用。 可以提供一個(gè) options 對(duì)象決定如何調(diào)用 func 方法, options.leading 與|或 options.trailing 決定 wait 前后如何觸發(fā)。 func 會(huì)傳入最后一次傳入的參數(shù)給這個(gè)函數(shù)。 隨后調(diào)用的函數(shù)返回是最后一次 func 調(diào)用的結(jié)果。

注意: 如果 leading 和 trailing 都設(shè)定為 true 則 func 允許 trailing 方式調(diào)用的條件為: 在 wait 期間多次調(diào)用。

如果 wait 為 0 并且 leading 為 false, func調(diào)用將被推遲到下一個(gè)點(diǎn),類似setTimeout為0的超時(shí)。

參數(shù)

func (Function)
要節(jié)流的函數(shù)

[wait=0] (number)
需要節(jié)流的毫秒

[options] (Object)
選項(xiàng)對(duì)象

[options.leading=true] (boolean)
指定調(diào)用在節(jié)流開始前

[options.trailing=true] (boolean)
指定調(diào)用在節(jié)流結(jié)束后

返回值 (Function)

返回節(jié)流的函數(shù)

示例

// 避免在滾動(dòng)時(shí)過分的更新定位
jQuery(window).on('scroll', _.throttle(updatePosition, 100));

// 點(diǎn)擊后就調(diào)用 `renewToken`,但5分鐘內(nèi)超過1次。
var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
jQuery(element).on('click', throttled);

// 取消一個(gè) trailing 的節(jié)流調(diào)用
jQuery(window).on('popstate', throttled.cancel);

防抖(debounce)

創(chuàng)建一個(gè) debounced(防抖動(dòng))函數(shù),該函數(shù)會(huì)從上一次被調(diào)用后,延遲 wait 毫秒后調(diào)用 func 方法。 debounced(防抖動(dòng))函數(shù)提供一個(gè) cancel 方法取消延遲的函數(shù)調(diào)用以及 flush 方法立即調(diào)用。 可以提供一個(gè) options(選項(xiàng)) 對(duì)象決定如何調(diào)用 func 方法,options.leading 與 options.trailing 決定延遲前后如何觸發(fā)(先調(diào)用后等待 還是 先等待后調(diào)用)。 func 調(diào)用時(shí)會(huì)傳入最后一次提供給 debounced(防抖動(dòng))函數(shù) 的參數(shù)。 后續(xù)調(diào)用的 debounced(防抖動(dòng))函數(shù)返回是最后一次 func 調(diào)用的結(jié)果。

注意: 如果 leading 和 trailing 選項(xiàng)為 true, 則 func 允許 trailing 方式調(diào)用的條件為: 在 wait 期間多次調(diào)用防抖方法。

如果 wait 為 0 并且 leading 為 false, func調(diào)用將被推遲到下一個(gè)點(diǎn),類似setTimeout為0的超時(shí)。

參數(shù)

func (Function)
要防抖動(dòng)的函數(shù)

[wait=0] (number)
需要延遲的毫秒數(shù)

[options] (Object)
選項(xiàng)對(duì)象

[options.leading=false] (boolean)
指定調(diào)用在延遲開始前

[options.maxWait] (number)
設(shè)置 func 允許被延遲的最大值

[options.trailing=true] (boolean)
指定調(diào)用在延遲結(jié)束后

返回值 (Function)

返回具有防抖動(dòng)功能的函數(shù)

示例

// 避免窗口在變動(dòng)時(shí)出現(xiàn)昂貴的計(jì)算開銷。
jQuery(window).on('resize', _.debounce(calculateLayout, 150));

// 當(dāng)點(diǎn)擊時(shí) `sendMail` 隨后就被調(diào)用。
jQuery(element).on('click', _.debounce(sendMail, 300, {
 'leading': true,
 'trailing': false
}));

// 確保 `batchLog` 調(diào)用1次之后,1秒內(nèi)會(huì)被觸發(fā)。
var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
var source = new EventSource('/stream');
jQuery(source).on('message', debounced);

// 取消一個(gè) trailing 的防抖動(dòng)調(diào)用
jQuery(window).on('popstate', debounced.cancel);

以上就是這篇節(jié)流和防抖的全部介紹,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JS字符串處理實(shí)例代碼

    JS字符串處理實(shí)例代碼

    這篇文章介紹了JS字符串處理實(shí)例代碼,有需要的朋友可以參考一下
    2013-08-08
  • javascript中String對(duì)象的slice()方法分析

    javascript中String對(duì)象的slice()方法分析

    這篇文章主要介紹了javascript中String對(duì)象的slice()方法,以實(shí)例形式分析了slice()方法的定義、參數(shù)與具體用法,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-12-12
  • 微信小程序?qū)崿F(xiàn)保存影集和圖片到相冊(cè)

    微信小程序?qū)崿F(xiàn)保存影集和圖片到相冊(cè)

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)保存影集和圖片到相冊(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 理解JavaScript的caller,callee,call,apply

    理解JavaScript的caller,callee,call,apply

    文章挺好的,雖然我用的是jQuery,但感覺還是有些用的~~~
    2009-04-04
  • 關(guān)于對(duì)TypeScript泛型參數(shù)的默認(rèn)值理解

    關(guān)于對(duì)TypeScript泛型參數(shù)的默認(rèn)值理解

    泛型可以理解為寬泛的類型,通常用于類和函數(shù),下面這篇文章主要給大家介紹了關(guān)于對(duì)TypeScript泛型參數(shù)默認(rèn)值的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • JavaScript中cookie工具函數(shù)封裝的示例代碼

    JavaScript中cookie工具函數(shù)封裝的示例代碼

    這篇文章給大家主要介紹了JavaScript中cookie工具函數(shù)的封裝,文中給出了詳細(xì)的實(shí)現(xiàn)步驟和示例代碼,相信會(huì)對(duì)大家的理解很有幫助,有需要的朋友們下面來一起看看吧。
    2016-10-10
  • JS建造者模式基本用法實(shí)例分析

    JS建造者模式基本用法實(shí)例分析

    這篇文章主要介紹了JS建造者模式基本用法,以一個(gè)完整實(shí)例形式較為詳細(xì)的分析了javascript建造者模式的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2015-06-06
  • 在uniapp中實(shí)現(xiàn)中英文切換的方法

    在uniapp中實(shí)現(xiàn)中英文切換的方法

    最近使用uniapp做了個(gè)APP,由于客戶是巴西的,所以使用中文已經(jīng)滿足不了客戶需求了,本打算直接使用英文開發(fā)算了,老板非要做成可以中英文切換的,沒辦法只能開干,需要的朋友可以參考下
    2023-11-11
  • JavaScript實(shí)現(xiàn)顯示隱藏表單文字

    JavaScript實(shí)現(xiàn)顯示隱藏表單文字

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)顯示隱藏表單文字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JavaScript閉包實(shí)例講解

    JavaScript閉包實(shí)例講解

    眾所周知,JavaScript沒有塊級(jí)作用域,只有函數(shù)作用域。那就意味著定義在函數(shù)中的參數(shù)和變量在函數(shù)外部是不可見的,而在一個(gè)函數(shù)內(nèi)部任何位置定義的變量,在該函數(shù)內(nèi)部任何地方都可見
    2014-04-04

最新評(píng)論

达州市| 永济市| 南川市| 景东| 晋中市| 沁阳市| 龙口市| 从化市| 保德县| 彰化县| 响水县| 监利县| 水城县| 景宁| 余江县| 呈贡县| 宜春市| 勐海县| 静宁县| 杨浦区| 清苑县| 临沂市| 涪陵区| 拜城县| 息烽县| 大田县| 通河县| 额尔古纳市| 新余市| 灵山县| 临泽县| 吐鲁番市| 寻甸| 南汇区| 哈尔滨市| 沐川县| 揭阳市| 桂平市| 佛山市| 白山市| 永德县|