摘要:直接來分析返回的匿名函數部分。我第一次調用事件函數是在,按照設定,之后才能調用第二次方法,在這秒內,任何調用都是不執行的。這個難點解決了,其他就都好說。恩,那這個的解讀就結束了,有什么地方我沒寫清楚的話,請給我留言。
剛寫完一篇debounce(防抖)函數的實現,我又看了下underscore.js的實現方法。算是趁熱打鐵,分析一下underscore里實現的套路。
先貼上源碼:
_.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){ // 函數的回調部分 // 當immediate === false時 // func真正的執行部分 function later(){}; return function(){ // 在這里判斷func是否立即執行 // 是否有計時器的存在 } }
上一篇文章已經分析過this的指向和event的傳遞,這里就不多說了。直接來分析返回的匿名函數部分。
return function() { context = this; args = arguments; // 這里調用了underscore封裝的調用時間戳的方法 // 等同于 // 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,它存儲的是動作發生時的時間戳,假設我這里調用debounce時傳入的wait為10000,也就是10秒。我第一次調用事件函數是在10:00:00,按照設定,10:00:10之后才能調用第二次方法,在這10秒內,任何調用都是不執行的。
當我第一次執行事件時
timeout = undefined; immediate先設置為false
所以
callNow === false
只有這句話是執行的
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內重復輸入,我們取消事件的方法是這樣的
if(timer){clearTimeout(timer)}
但在這里,我們是不是都還沒看到怎么處理wait時間內,重復輸入無效的問題?別急,現在就來說。玄妙都在這個last變量上。
之前說過,timestamp存儲的是第一次事件執行時的時間戳(10:00:00),但現在我沒想等十秒,過了五秒我就觸發了第二次事件。所以timestamp現在的內容就變成新的時間戳了(10:00:05)。但問題是,timer的回調函數至少要到10:00:10之后才會執行,也就是說
last>=5
由于代碼執行堵塞導致last>10的情況有可能存在,但是不符合我們現在討論的,而且真的是太特殊了,我們就不說了。那就假設last為5秒(5000ms)。
last < wait && last >= 0
這句話就是true,那就執行里面的代碼。但注意看里面計時器對于時間的寫法。
wait - last
換個說法就是,你在10:00:00啟動了我,但是你在10:00:05又動了,我原本應該在10:00:10執行,但是現在懲罰你提前行動,那你之前等的時間就不算,你要再重新多等這幾秒10:00:15。
這個難點解決了,其他就都好說。
lster剩余的部分就是判斷如果當初設置的是立即執行(immediate = true),func就不再執行一遍了,否則(immediate = false)func執行。
恩,那這個的解讀就結束了,有什么地方我沒寫清楚的話,請給我留言。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92012.html
摘要:如果想忽略結尾邊界上的調用,傳入返回客戶調用函數上次執行時間點延遲執行函數若設定了開始邊界不執行選項,上次執行時間始終為首次執行時,如果設定了開始邊界不執行選項,將上次執行時間設定為當前時間。 文章轉自:https://blog.coding.net/blog/...注: _.throttle 和 _.debounce是Underscore.js庫的兩個針對函數節流的方法,用于處理高頻...
摘要:函數節流和去抖的出現場景,一般都伴隨著客戶端的事件監聽。函數節流的核心是,讓一個函數不要執行得太頻繁,減少一些過快的調用來節流。 概述 也是好久沒更新 源碼解讀,看著房價蹭蹭暴漲,心里也是五味雜陳,對未來充滿恐懼和迷茫 ...(敢問一句你們上岸了嗎) 言歸正傳,今天要介紹的是 underscore 中兩個重要的方法,函數節流和函數去抖。這篇文章不會涉及具體的代碼實現(關于代碼實現請期...
摘要:專題系列共計篇,主要研究日常開發中一些功能點的實現,比如防抖節流去重類型判斷拷貝最值扁平柯里遞歸亂序排序等,特點是研究專題之函數組合專題系列第十六篇,講解函數組合,并且使用柯里化和函數組合實現模式需求我們需要寫一個函數,輸入,返回。 JavaScript 專題之從零實現 jQuery 的 extend JavaScritp 專題系列第七篇,講解如何從零實現一個 jQuery 的 ext...
摘要:寫在前面專題系列是我寫的第二個系列,第一個系列是深入系列。專題系列自月日發布第一篇文章,到月日發布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 專題系列是我寫的第二個系列,第一個系列是 JavaScript 深入系列。 JavaScript 專題系列共計 20 篇,主要研究日常開發中一些功能點的實現,比如防抖、節流、去重、類型判斷、拷貝、最值、扁平、柯里...
摘要:事情是如何發生的最近干了件事情,發現了源碼的一個。樓主找到的關于和區別的資料如下關于拿來主義為什么這么多文章里會出現澤卡斯的錯誤代碼樓主想到了一個詞,叫做拿來主義。的文章,就深刻抨擊了拿來主義這一現象。 事情是如何發生的 最近干了件事情,發現了 underscore 源碼的一個 bug。這件事本身并沒有什么可說的,但是過程值得我們深思,記錄如下,各位看官仁者見仁智者見智。 平時有瀏覽別...
閱讀 3304·2021-11-18 10:02
閱讀 2751·2019-08-30 13:56
閱讀 407·2019-08-29 12:36
閱讀 521·2019-08-28 18:07
閱讀 712·2019-08-27 10:51
閱讀 3449·2019-08-26 12:13
閱讀 3286·2019-08-26 11:46
閱讀 3315·2019-08-23 12:00