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