成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

underscore源碼解讀之debounce

Flink_China / 2032人閱讀

摘要:直接來分析返回的匿名函數(shù)部分。我第一次調(diào)用事件函數(shù)是在,按照設(shè)定,之后才能調(diào)用第二次方法,在這秒內(nèi),任何調(diào)用都是不執(zhí)行的。這個難點解決了,其他就都好說。恩,那這個的解讀就結(jié)束了,有什么地方我沒寫清楚的話,請給我留言。

剛寫完一篇debounce(防抖)函數(shù)的實現(xiàn),我又看了下underscore.js的實現(xiàn)方法。算是趁熱打鐵,分析一下underscore里實現(xiàn)的套路。

先貼上源碼:

_.debounce = function(func, wait, immediate) {
    var timeout, args, context, timestamp, result;

    var later = function() {
        var last = _.now() - timestamp;
        console.log(last)
        if (last < wait && last >= 0) {
            console.log(1)
            timeout = setTimeout(later, wait - last);
        } else {
            console.log(2)
            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;
        console.log(timeout)
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
};

一看可能有點多,我簡化一下,整體其實就兩部分:

_.debounce = function( func, wait, immediate){

    // 函數(shù)的回調(diào)部分
    // 當immediate === false時
    // func真正的執(zhí)行部分
    function later(){};
    
    return function(){
        // 在這里判斷func是否立即執(zhí)行
        // 是否有計時器的存在
    }
}

上一篇文章已經(jīng)分析過this的指向和event的傳遞,這里就不多說了。直接來分析返回的匿名函數(shù)部分。

return function() {
        context = this;
        args = arguments;
        // 這里調(diào)用了underscore封裝的調(diào)用時間戳的方法
        // 等同于
        // timestamp = Date.now()
        timestamp = _.now();
        var callNow = immediate && !timeout;
        console.log(timeout)
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }
    };

這里我要說的是timestamp,它存儲的是動作發(fā)生時的時間戳,假設(shè)我這里調(diào)用debounce時傳入的wait為10000,也就是10秒。我第一次調(diào)用事件函數(shù)是在10:00:00,按照設(shè)定,10:00:10之后才能調(diào)用第二次方法,在這10秒內(nèi),任何調(diào)用都是不執(zhí)行的。

當我第一次執(zhí)行事件時

timeout = undefined;
immediate先設(shè)置為false

所以

callNow === false

只有這句話是執(zhí)行的

if (!timeout) timeout = setTimeout(later, wait);

那接著來看later都有什么:

var later = function() {
  //     var last = Date.now() - timestamp;
    var last = _.now() - timestamp;
    console.log(last)
    if (last < wait && last >= 0) {
        console.log(1)
        timeout = setTimeout(later, wait - last);
    } else {
        console.log(2)
        timeout = null;
        if (!immediate) {
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        }
    }
};

在上一篇中,判斷wait內(nèi)重復(fù)輸入,我們?nèi)∠录姆椒ㄊ沁@樣的

if(timer){clearTimeout(timer)}

但在這里,我們是不是都還沒看到怎么處理wait時間內(nèi),重復(fù)輸入無效的問題?別急,現(xiàn)在就來說。玄妙都在這個last變量上。

之前說過,timestamp存儲的是第一次事件執(zhí)行時的時間戳(10:00:00),但現(xiàn)在我沒想等十秒,過了五秒我就觸發(fā)了第二次事件。所以timestamp現(xiàn)在的內(nèi)容就變成新的時間戳了(10:00:05)。但問題是,timer的回調(diào)函數(shù)至少要到10:00:10之后才會執(zhí)行,也就是說

last>=5

由于代碼執(zhí)行堵塞導(dǎo)致last>10的情況有可能存在,但是不符合我們現(xiàn)在討論的,而且真的是太特殊了,我們就不說了。那就假設(shè)last為5秒(5000ms)。

last < wait && last >= 0

這句話就是true,那就執(zhí)行里面的代碼。但注意看里面計時器對于時間的寫法。

wait - last

換個說法就是,你在10:00:00啟動了我,但是你在10:00:05又動了,我原本應(yīng)該在10:00:10執(zhí)行,但是現(xiàn)在懲罰你提前行動,那你之前等的時間就不算,你要再重新多等這幾秒10:00:15。

這個難點解決了,其他就都好說。

lster剩余的部分就是判斷如果當初設(shè)置的是立即執(zhí)行(immediate = true),func就不再執(zhí)行一遍了,否則(immediate = false)func執(zhí)行。

恩,那這個的解讀就結(jié)束了,有什么地方我沒寫清楚的話,請給我留言。

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/92012.html

相關(guān)文章

  • 淺談 Underscore.js 中 _.throttle 和 _.debounce 的差異

    摘要:如果想忽略結(jié)尾邊界上的調(diào)用,傳入返回客戶調(diào)用函數(shù)上次執(zhí)行時間點延遲執(zhí)行函數(shù)若設(shè)定了開始邊界不執(zhí)行選項,上次執(zhí)行時間始終為首次執(zhí)行時,如果設(shè)定了開始邊界不執(zhí)行選項,將上次執(zhí)行時間設(shè)定為當前時間。 文章轉(zhuǎn)自:https://blog.coding.net/blog/...注: _.throttle 和 _.debounce是Underscore.js庫的兩個針對函數(shù)節(jié)流的方法,用于處理高頻...

    alighters 評論0 收藏0
  • JavaScript 函數(shù)節(jié)流和函數(shù)去抖應(yīng)用場景辨析

    摘要:函數(shù)節(jié)流和去抖的出現(xiàn)場景,一般都伴隨著客戶端的事件監(jiān)聽。函數(shù)節(jié)流的核心是,讓一個函數(shù)不要執(zhí)行得太頻繁,減少一些過快的調(diào)用來節(jié)流。 概述 也是好久沒更新 源碼解讀,看著房價蹭蹭暴漲,心里也是五味雜陳,對未來充滿恐懼和迷茫 ...(敢問一句你們上岸了嗎) 言歸正傳,今天要介紹的是 underscore 中兩個重要的方法,函數(shù)節(jié)流和函數(shù)去抖。這篇文章不會涉及具體的代碼實現(xiàn)(關(guān)于代碼實現(xiàn)請期...

    ZHAO_ 評論0 收藏0
  • JavaScript專題系列文章

    摘要:專題系列共計篇,主要研究日常開發(fā)中一些功能點的實現(xiàn),比如防抖節(jié)流去重類型判斷拷貝最值扁平柯里遞歸亂序排序等,特點是研究專題之函數(shù)組合專題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實現(xiàn)模式需求我們需要寫一個函數(shù),輸入,返回。 JavaScript 專題之從零實現(xiàn) jQuery 的 extend JavaScritp 專題系列第七篇,講解如何從零實現(xiàn)一個 jQuery 的 ext...

    Maxiye 評論0 收藏0
  • JavaScript專題系列20篇正式完結(jié)!

    摘要:寫在前面專題系列是我寫的第二個系列,第一個系列是深入系列。專題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 專題系列是我寫的第二個系列,第一個系列是 JavaScript 深入系列。 JavaScript 專題系列共計 20 篇,主要研究日常開發(fā)中一些功能點的實現(xiàn),比如防抖、節(jié)流、去重、類型判斷、拷貝、最值、扁平、柯里...

    sixleaves 評論0 收藏0
  • 一次發(fā)現(xiàn)underscore源碼bug的經(jīng)歷以及對學術(shù)界拿來主義的思考

    摘要:事情是如何發(fā)生的最近干了件事情,發(fā)現(xiàn)了源碼的一個。樓主找到的關(guān)于和區(qū)別的資料如下關(guān)于拿來主義為什么這么多文章里會出現(xiàn)澤卡斯的錯誤代碼樓主想到了一個詞,叫做拿來主義。的文章,就深刻抨擊了拿來主義這一現(xiàn)象。 事情是如何發(fā)生的 最近干了件事情,發(fā)現(xiàn)了 underscore 源碼的一個 bug。這件事本身并沒有什么可說的,但是過程值得我們深思,記錄如下,各位看官仁者見仁智者見智。 平時有瀏覽別...

    Lionad-Morotar 評論0 收藏0

發(fā)表評論

0條評論

Flink_China

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<