国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端進(jìn)擊的巨人(八):淺談函數(shù)防抖與節(jié)流

_Zhao / 2488人閱讀

摘要:隆重請(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é)流

本篇課題,或許早已是爛大街的解讀文章。不過(guò)春招系列面試下來(lái),不少伙伴們還是似懂非懂地栽倒在(~面試官~)深意的笑容之下,權(quán)當(dāng)溫故知新。

JavaScript的執(zhí)行過(guò)程,是基于棧來(lái)進(jìn)行的。復(fù)雜的程序代碼被封裝到函數(shù)中,程序執(zhí)行時(shí),函數(shù)不斷被推入執(zhí)行棧中。所以 "執(zhí)行棧" 也稱 "函數(shù)執(zhí)行棧"

函數(shù)中封裝的代碼塊,一般都有相對(duì)復(fù)雜的邏輯處理(計(jì)算/判斷),例如函數(shù)中可能會(huì)涉及到 DOM 的渲染更新,復(fù)雜的計(jì)算與驗(yàn)證, Ajax 數(shù)據(jù)請(qǐng)求等等。

前端頁(yè)面的操作權(quán),大部分都是屬于瀏覽端的客戶爸爸們(單身三十年的手速,惹不起惹不起!!!)。如果函數(shù)被頻繁調(diào)用,造成的性能開銷絕對(duì)不只一點(diǎn)點(diǎn)。

前: DOM 頻繁重繪的卡頓讓客戶爸爸們想把你揪出來(lái)一頓大招。。。

后: 后端同學(xué)正在提刀趕來(lái)的路上:“為什么我的接口被你玩掛了”。。。

既要提升用戶體驗(yàn),又要減少后端服務(wù)開銷,可見(jiàn)我們大前端的使命不只一頁(yè)P(yáng)PT。說(shuō)好前因,接著就是后果了。既然有優(yōu)化的需求,必然就要有相應(yīng)的解決方案。隆重請(qǐng)出主角: “防抖”“節(jié)流”

防抖(debounce)
在事件被觸發(fā) n 秒后再執(zhí)行回調(diào)函數(shù),如果在這 n 秒內(nèi)又被觸發(fā),則重新計(jì)時(shí)延遲時(shí)間。

生活化理解:英雄的技能條,技能條讀完才能使用技能(R大招60s)

防抖的實(shí)現(xiàn)方式分兩種 “立即執(zhí)行”“非立即執(zhí)行”,區(qū)別在于第一次觸發(fā)時(shí),是否立即執(zhí)行回調(diào)函數(shù)。

非立即執(zhí)行
”非立即執(zhí)行防抖“ 指事件觸發(fā)后,回調(diào)函數(shù)不會(huì)立即執(zhí)行,會(huì)在延遲時(shí)間 n 秒后執(zhí)行,如果 n 秒內(nèi)被調(diào)用多次,則重新計(jì)時(shí)延遲時(shí)間
// e.g. 防抖 - 非立即執(zhí)行
function debounce(func, delay) {
  var timeout;
  return function() {
    var context = this;
    var args = arguments;
    // && 短路運(yùn)算 == if(timeout) else {...} 
    timeout && clearTimeout(timeout); 
    timeout = setTimeout(function(){
      func.apply(context, args);
    }, delay);
  }
}

// 調(diào)用
var printUserName = debounce(function(){ 
  console.log(this.value);
}, 800);
document.getElementById("username")
  .addEventListener("keyup", printUserName);
立即執(zhí)行
“立即執(zhí)行防抖” 指事件觸發(fā)后,回調(diào)函數(shù)會(huì)立即執(zhí)行,之后要想觸發(fā)執(zhí)行回調(diào)函數(shù),需等待 n 秒延遲
// e.g. 防抖 - 立即執(zhí)行
function debounce(func, delay) {
    var timeout;
    return function() {
        var context = this;
        var args = arguments;
        callNow = !timeout;
        timeout = setTimeout(function() {
            timeout = null;
        }, delay);
        callNow && func.apply(context, args);
    }
}

函數(shù)防抖原理:通過(guò)維護(hù)一個(gè)定時(shí)器,其延遲計(jì)時(shí)以最后一次觸發(fā)為計(jì)時(shí)起點(diǎn),到達(dá)延遲時(shí)間后才會(huì)觸發(fā)函數(shù)執(zhí)行。

節(jié)流(throttle)
規(guī)定在一個(gè)單位時(shí)間內(nèi),只能觸發(fā)一次函數(shù)。如果這個(gè)單位時(shí)間內(nèi)觸發(fā)多次函數(shù),只有一次生效(間隔執(zhí)行)

生活化理解:

FPS射擊游戲子彈射速(即使按住鼠標(biāo)左鍵,射出子彈的速度也是限定的)

水龍頭的滴水(水滴攢到一定重量才會(huì)下落)

函數(shù)節(jié)流實(shí)現(xiàn)的方式有 “時(shí)間戳”“定時(shí)器” 兩種。

時(shí)間戳
// e.g. 節(jié)流 - 時(shí)間戳
function throttle(func, delay) {
  var lastTime = 0;
  return function() {
    var context = this;
    var args = arguments;
    var nowTime = +new Date();
    if (nowTime > lastTime + delay) {
      func.apply(context, args)
      lastTime = nowTime;
    }
  }
}

“時(shí)間戳” 的方式,函數(shù)在時(shí)間段開始時(shí)執(zhí)行。

缺點(diǎn):假定函數(shù)間隔1s執(zhí)行,如果最后一次停止觸發(fā),卡在4.2s,則不會(huì)再執(zhí)行。

定時(shí)器
// e.g. 節(jié)流 - 定時(shí)器
function throttle(func, delay) {
  var timeout;
  return function() {
    var context = this;
    var args = arguments;
    if (!timeout) {
      setTimeout(function(){
        func.apply(context, args);
        timeout = null;
      }, delay)
    }
  }
}

“定時(shí)器” 的方式,函數(shù)在時(shí)間段結(jié)束時(shí)執(zhí)行。可理解為函數(shù)并不會(huì)立即執(zhí)行,而是等待延遲計(jì)時(shí)完成才執(zhí)行。(由于定時(shí)器延時(shí),最后一次觸發(fā)后,可能會(huì)再執(zhí)行一次回調(diào)函數(shù))

時(shí)間戳 + 定時(shí)器(互補(bǔ)優(yōu)化)
// e.g. 節(jié)流 - 時(shí)間戳 + 定時(shí)器
function throttle(func, delay) {
  let lastTime, timeout;
  return function() {
    let context = this;
    let args = arguments;
    let nowTime = +new Date();
    if (lastTime && nowTime < lastTime + delay) {
      timeout && clearTimeout(timeout);
      timeout = setTimeout(function(){
        lastTime = nowTime;
        func.apply(context, args);
      }, delay);
    } else {
      lastTime = nowTime;
      func.apply(context, args);
    }
  }
}

合并優(yōu)化的原理:“時(shí)間戳”方式讓函數(shù)在時(shí)間段開始時(shí)執(zhí)行(第一次觸發(fā)立即執(zhí)行),“定時(shí)器”方式讓函數(shù)在最后一次事件觸發(fā)后(如4.2s)也能觸發(fā)。

函數(shù)節(jié)流原理:一定時(shí)間內(nèi)只觸發(fā)一次,間隔執(zhí)行。通過(guò)判斷是否到達(dá)指定觸發(fā)時(shí)間,間隔時(shí)間固定。

“防抖” 與 “節(jié)流” 的異同

相同:都是防止某一時(shí)間段內(nèi),函數(shù)被頻繁調(diào)用執(zhí)行,通過(guò)時(shí)間頻率控制,減少回調(diào)函數(shù)執(zhí)行次數(shù),來(lái)實(shí)現(xiàn)相關(guān)性能優(yōu)化。

區(qū)別:“防抖”是某一時(shí)間內(nèi)只執(zhí)行一次,最后一次觸發(fā)后過(guò)段時(shí)間執(zhí)行,而“節(jié)流”則是間隔時(shí)間執(zhí)行,間隔時(shí)間固定。

“防抖” 與 “節(jié)流” 的應(yīng)用場(chǎng)景 防抖

文本輸入搜索聯(lián)想

文本輸入驗(yàn)證(包括 Ajax 后端驗(yàn)證)

節(jié)流

鼠標(biāo)點(diǎn)擊

監(jiān)聽滾動(dòng) scroll

窗口 resize

mousemove 拖拽

應(yīng)用場(chǎng)景還有很多,具體場(chǎng)景需具體分析。只要涉及高頻的函數(shù)調(diào)用,都可參考函數(shù)防抖節(jié)流的優(yōu)化方案。

鼓起勇氣寫在結(jié)尾:以上代碼都不是 “完美” 的 “防抖 / 節(jié)流” 實(shí)現(xiàn)代碼!!!僅就實(shí)現(xiàn)方式和基本原理,淺談分解一二。

實(shí)際代碼開發(fā)中,一般會(huì)引入lodash 相對(duì) “靠譜” 的第三方庫(kù),幫我們?nèi)?shí)現(xiàn)防抖節(jié)流的工具函數(shù)。有興趣的伙伴們可閱讀 lodash 相關(guān)源碼,加深印象理解可再讀以下參考文章。

參考文章

7分鐘理解JS的節(jié)流、防抖及使用場(chǎng)景

函數(shù)防抖和節(jié)流

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/102343.html

相關(guān)文章

  • 高級(jí)函數(shù)技巧-函數(shù)抖與節(jié)流

    摘要:封裝方法也比較簡(jiǎn)單,書中對(duì)此問(wèn)題也進(jìn)行了處理使用定時(shí)器,讓函數(shù)延遲秒后執(zhí)行,在此秒內(nèi),然后函數(shù)再次被調(diào)用,則刪除上次的定時(shí)器,取消上次調(diào)用的隊(duì)列任務(wù),重新設(shè)置定時(shí)器。 在實(shí)際開發(fā)中,函數(shù)一定是最實(shí)用最頻繁的一部分,無(wú)論是以函數(shù)為核心的函數(shù)式編程,還是更多人選擇的面向?qū)ο笫降木幊蹋紩?huì)有函數(shù)的身影,所以對(duì)函數(shù)進(jìn)行深入的研究是非常有必要的。 函數(shù)節(jié)流 比較直白的說(shuō),函數(shù)節(jié)流就是強(qiáng)制規(guī)定一...

    whinc 評(píng)論0 收藏0
  • 小菊花課堂之JS抖與節(jié)流

    摘要:文章來(lái)源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學(xué)問(wèn)無(wú)遺力,少壯工夫老始成。紙上得來(lái)終覺(jué)淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩(shī)的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...

    leoperfect 評(píng)論0 收藏0
  • 小菊花課堂之JS抖與節(jié)流

    摘要:文章來(lái)源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內(nèi)容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學(xué)問(wèn)無(wú)遺力,少壯工夫老始成。紙上得來(lái)終覺(jué)淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學(xué)習(xí)或工作中,不斷的印證著這首詩(shī)的內(nèi)涵。所以,又有了此篇小菊花文章。 詳解 在前端開發(fā)中,我們經(jīng)常會(huì)碰到一些會(huì)持...

    Yangder 評(píng)論0 收藏0
  • 前端進(jìn)擊巨人(五):學(xué)會(huì)函數(shù)柯里化(curry)

    摘要:函數(shù)柯里化是把支持多個(gè)參數(shù)的函數(shù)變成接收單一參數(shù)的函數(shù),并返回一個(gè)函數(shù)能接收處理剩余參數(shù),而反柯里化就是把參數(shù)全部釋放出來(lái)。但在一些復(fù)雜的業(yè)務(wù)邏輯封裝中,函數(shù)柯里化能夠?yàn)槲覀兲峁└玫膽?yīng)對(duì)方案,讓我們的函數(shù)更具自由度和靈活性。 showImg(https://segmentfault.com/img/bVburN1?w=800&h=600); 柯里化(Curring, 以邏輯學(xué)家Has...

    chengtao1633 評(píng)論0 收藏0
  • 前端筆記(二) 對(duì)象深淺拷貝,函數(shù)抖與節(jié)流函數(shù)柯里化 ,圖片預(yù)加載與懶加載

    摘要:對(duì)象是無(wú)法通過(guò)這種方式深拷貝。這就是函數(shù)防抖和節(jié)流要做的事情。函數(shù)防抖當(dāng)觸發(fā)頻率過(guò)高時(shí)函數(shù)基本停止執(zhí)行而函數(shù)節(jié)流則是按照一定的頻率執(zhí)行事件。 對(duì)象的深淺拷貝 對(duì)象的深拷貝與淺拷貝的區(qū)別: 淺拷貝:僅僅復(fù)制對(duì)象的引用, 而不是對(duì)象本身。 深拷貝:把復(fù)制的對(duì)象所引用的全部對(duì)象都復(fù)制一遍 淺拷貝的實(shí)現(xiàn): var obj = { age : 18, person : { ...

    dongxiawu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<