極度重要之定時(shí)器

說到定時(shí)器庶艾,大家就肯定知道setTimeout()和setImterval(),但是他們背后還有很多更重要的知識點(diǎn)需要我們?nèi)フ莆?br> 首先我們重新了解一下定時(shí)器的用法
JavaScript提供了定時(shí)執(zhí)行代碼的功能彪蓬,叫做定時(shí)器(timer)娘赴,主要由setTimeout()和setInterval()這兩個(gè)函數(shù)來完成,用法如下

setTimeout()

指定某個(gè)函數(shù)或者代碼段,在多少毫秒內(nèi)執(zhí)行,會返回一個(gè)編號呜达,編號可以用來取消這個(gè)定時(shí)器

var timer = setTimeout(func | code ,delay)
console.log(1);
setTimeout('console.log(2)',1000);
console.log(3);
//輸出 1 3 2  因?yàn)閟etTimeout指定第二行語句推遲1000毫秒再執(zhí)行

需要注意的是,推遲執(zhí)行的代碼必須以字符串的形式粟耻,放入setTimeout查近,因?yàn)橐鎯?nèi)部使用eval函數(shù),將字符串轉(zhuǎn)為代碼挤忙。如果推遲執(zhí)行的是函數(shù)霜威,則可以直接將函數(shù)名,放入setTimeout册烈。一方面eval函數(shù)有安全顧慮戈泼,另一方面為了便于JavaScript引擎優(yōu)化代碼,setTimeout方法一般總是采用函數(shù)名的形式,就像下面這樣大猛。

setTimeout(function (){console.log(2)},1000);

setInterval()

setInterval函數(shù)的用法與setTimeout完全一致扭倾,區(qū)別僅僅在于setInterval指定某個(gè)任務(wù)每隔一段時(shí)間就執(zhí)行一次,也就是無限次的定時(shí)執(zhí)行挽绩。

var i = 1
 var timer = setInterval(function() {
   console.log(i++);
 }, 1000);

定時(shí)器有觸發(fā)就有停止


setTimeout和setInterval函數(shù)膛壹,都返回一個(gè)表示計(jì)數(shù)器編號的整數(shù)值,將該整數(shù)傳入clearTimeout和clearInterval函數(shù)唉堪,就可以取消對應(yīng)的定時(shí)器模聋。

var id1 = setTimeout(f,1000);
var id2 = setInterval(f,1000);

clearTimeout(id1);  
clearInterval(id2);

1.異步
2.節(jié)流
首先我們了解一下什么是異步
我們js的運(yùn)行機(jī)制,一般情況下是從上至下的執(zhí)行唠亚,這就是很舒服撬槽,讓人看起來也很容易理解,就比方有是一個(gè)保姆趾撵,每次做完一件事再去做一件事侄柔,那總會有一些特殊情況發(fā)生,比如說占调,保姆今天需要做的事是暂题,打掃衛(wèi)生,拿快遞究珊,買菜薪者,做飯,但是這個(gè)保姆比較笨剿涮,快遞小哥打電話給他的時(shí)候?qū)λf:"麻煩你過三十分鐘的時(shí)候去樓下拿一下快遞言津,我準(zhǔn)時(shí)到!",這個(gè)時(shí)候保姆就慌的一筆,這尼瑪那個(gè)時(shí)候我事做沒做完都不知道取试,他自然有自己的方法悬槽,對著小哥說:“那個(gè)麻煩你等一下,我需要把事情做完再去那快遞瞬浓,所以我一會打電話給你你在30分鐘后到我樓下把”初婆,沒辦法,快遞小哥只能同意了猿棉。這就是異步
就是把一件事放在最后面的做磅叛,并不和其他事攙和著同時(shí)去做,一件一件的完成萨赁,等做完了再去做剛才擱下的事(拿快遞)這個(gè)就是異步處理碰镜,也是單線程模型的特點(diǎn)召夹,很多語言都是這個(gè)特點(diǎn),比如php缠捌。
很費(fèi)解,為什么說定時(shí)器很重要呢晨继,因?yàn)槎〞r(shí)器和我們的js異步處理是密不可分的

setTimeout('console.log(2)',0);
console.log(1);
console.log(3);

上述的代碼按照正常的邏輯是輸入的應(yīng)該是2,1,3
但是我們運(yùn)行一下,就可以看出來,我們代碼運(yùn)行的是 1,3,2
why


1.jpg

我們js開始渲染的時(shí)候會開辟兩個(gè)空間,一個(gè)是正常執(zhí)行空間,放置一般的代碼段泻帮,一個(gè)是任務(wù)隊(duì)列精置,他們會把認(rèn)為耗時(shí)的,應(yīng)該在后面的函數(shù)或者代碼段放在任務(wù)隊(duì)列里面锣杂,也就是圖里面的webAPIs,DOM操作脂倦,ajax,定時(shí)器元莫。等正常執(zhí)行空間執(zhí)行完成之后赖阻,再去執(zhí)行任務(wù)隊(duì)列里里面的任務(wù)!(就好比最后拿快遞一個(gè)意思)
帶著這個(gè)思想踱蠢,我們再去理解一下上述代碼,首先計(jì)時(shí)器代碼被放置在任務(wù)隊(duì)列里面火欧,等其他兩個(gè)console.log()執(zhí)行完成之后再去執(zhí)行定時(shí)器代碼

2.節(jié)流
我們定時(shí)器中的setTimeout被使用后是每隔一段時(shí)間觸發(fā)一次內(nèi)部函數(shù),我們可以使用某種暴力的手法暫時(shí)暫停setTimeout的運(yùn)行茎截,就是節(jié)流苇侵,仔細(xì)閱讀下段代碼

var flag;
function  f1(){
   if (flag) {
           clearTimeout(flag)
      }
 flag = setInterval(function(){
      console.log('我每隔一秒就執(zhí)行,除非你調(diào)用f1函數(shù)打斷我')
      },5000)
 }
f1();

這段代碼的意思就是首先申明一個(gè)變量flag
申明函數(shù)在f1()函數(shù)內(nèi)進(jìn)行判斷企锌,如果flag變量不為空就暫停計(jì)時(shí)器榆浓,為空就觸發(fā)計(jì)時(shí)器控制console.log打印內(nèi)容,并調(diào)用函數(shù)f1()
但是這個(gè)時(shí)候打開控制臺的時(shí)候就會發(fā)現(xiàn)控制臺每隔五秒輸出一次‘我每隔五秒就執(zhí)行,除非你調(diào)用f1函數(shù)打斷我',但是我們在控制臺輸入f1()回車的時(shí)候就會發(fā)現(xiàn)暫時(shí)停止打印了撕攒,但是五秒過后又出現(xiàn)了打印內(nèi)容陡鹃。這個(gè)就是函數(shù)節(jié)流
函數(shù)節(jié)流我們可以理解成用一個(gè)小手法把定時(shí)器暫時(shí)停止

舉例說明:

  <input>

    docuemnt.querySelectorAll('input').addEventListener('keyup',function(){
        if(this.value === '') return
        if(this.timer) clearTimeout(this.timer)
        this.timer = setTimeout(()=>{
          console.log(this.value)
        },300)
    })    //實(shí)現(xiàn)一個(gè)300內(nèi)輸入支付不實(shí)行事件節(jié)流

           let oInput = document.querySelector('input')
                // oInput.addEventListener('input', function(e) {
                //     //如果直接每次onInput發(fā)請求,會導(dǎo)致性能問題
                //     console.log(e, this)
                // })

            oInput.addEventListener('input', debounce(callback, 500))

            function debounce(fn, delay) {
                let timer = null
                    // 綁定上下文this
                let self = this
                return function() {
                    let arg = arguments
                        // 每次清楚定時(shí)器
                    clearTimeout(timer)
                        // 重新打開定時(shí)器抖坪,做到只有最后一次執(zhí)行了
                    timer = setTimeout(() => {
                        // 綁定this萍鲸,傳入?yún)?shù)給callback。通常我們需要事件對象就ok
                        fn.apply(this, arg)
                    }, delay)
                }
            }

            function callback(e) {
                console.log('觸發(fā)', e.target.value)
            }
//世界節(jié)流  停止輸出后一秒鐘打印信息
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末擦俐,一起剝皮案震驚了整個(gè)濱河市猿推,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捌肴,老刑警劉巖蹬叭,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異状知,居然都是意外死亡秽五,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門饥悴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坦喘,“玉大人盲再,你說我怎么就攤上這事“晗常” “怎么了答朋?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棠笑。 經(jīng)常有香客問我梦碗,道長,這世上最難降的妖魔是什么蓖救? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任洪规,我火速辦了婚禮,結(jié)果婚禮上循捺,老公的妹妹穿的比我還像新娘斩例。我一直安慰自己,他們只是感情好从橘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布念赶。 她就那樣靜靜地躺著,像睡著了一般恰力。 火紅的嫁衣襯著肌膚如雪晶乔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天牺勾,我揣著相機(jī)與錄音正罢,去河邊找鬼。 笑死驻民,一個(gè)胖子當(dāng)著我的面吹牛翻具,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播回还,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼裆泳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柠硕?” 一聲冷哼從身側(cè)響起工禾,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝗柔,沒想到半個(gè)月后闻葵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡癣丧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年槽畔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胁编。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厢钧,死狀恐怖鳞尔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情早直,我是刑警寧澤寥假,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站霞扬,受9級特大地震影響糕韧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜祥得,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒋得。 院中可真熱鬧级及,春花似錦、人聲如沸额衙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窍侧。三九已至县踢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伟件,已是汗流浹背硼啤。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斧账,地道東北人谴返。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像咧织,于是被迫代替她去往敵國和親嗓袱。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容