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

資訊專欄INFORMATION COLUMN

對(duì)于“不用setInterval,用setTimeout”的理解

impig33 / 3250人閱讀

摘要:按照定時(shí)器的時(shí)間間隔,處第二個(gè)函數(shù)加入到事件隊(duì)列,但此時(shí)正在執(zhí)行,所以只能等待。這樣做的好處是,在前一個(gè)定時(shí)器代碼執(zhí)行完之前,不會(huì)向隊(duì)列插入新的定時(shí)器代碼,確保不會(huì)有任何缺失的間隔。

JavaScript高級(jí)程序設(shè)計(jì)(第三版)(以下簡(jiǎn)稱紅寶書(shū))22.3高級(jí)定時(shí)器中詳細(xì)介紹了定時(shí)器setTimeout和setInterval,看完書(shū)后,深入理解了二者的區(qū)別,結(jié)合前輩們給我的建議“用setTimeout,不要用setInterval”,寫下此文,分析這個(gè)建議的合理性。
這兩個(gè)家伙看上去長(zhǎng)得差不多,func是要執(zhí)行的函數(shù),interval是時(shí)間間隔。

setTimeout(func,interval)
setInterval(func,interval)

關(guān)于時(shí)間間隔,紅寶書(shū)中這么說(shuō):

設(shè)定一個(gè) 150ms 后執(zhí)行的定時(shí)器不代表到了 150ms 代碼就立刻執(zhí)行,它表示代碼會(huì)在 150ms 后被加入到隊(duì)列中。如果在這個(gè)時(shí)間點(diǎn)上,隊(duì)列中沒(méi)有其他東西,那么這段代碼就會(huì)被執(zhí)行。

對(duì)于這個(gè)時(shí)間間隔的理解非常重要!步入正題,為何不用setInterval,因?yàn)樗赡軙?huì)帶來(lái)兩個(gè)問(wèn)題:

“丟幀”現(xiàn)象

不同定時(shí)器的代碼的執(zhí)行間隔比預(yù)期小

一圖勝千言,如下圖所示,讓我們跟著時(shí)間線看看這樣的問(wèn)題怎么發(fā)生的。假定一個(gè)場(chǎng)景,在click事件中設(shè)置了setInterval(func,500),假設(shè)click事件和定時(shí)器內(nèi)函數(shù)的執(zhí)行時(shí)間都是1s,為了方便陳述,我把不同時(shí)間觸發(fā)的func取了不同的名字,實(shí)際上接下來(lái)的func1=func2=func3=func。在0s處觸發(fā)click事件,click事件執(zhí)行,在0.2s處觸發(fā)定時(shí)器,0.7s處第一個(gè)函數(shù)func1加入到事件隊(duì)列,但由于JS引擎是單線程的,click事件還在執(zhí)行,所以func1等待著,等到1s處,click事件執(zhí)行完畢,fun1才開(kāi)始執(zhí)行。按照定時(shí)器的時(shí)間間隔,1.2s處第二個(gè)函數(shù)func2加入到事件隊(duì)列,但此時(shí)fun1正在執(zhí)行,所以func2只能等待。0.5s后,也就是1.7s處,第三個(gè)函數(shù)func理應(yīng)加入事件隊(duì)列,但是JS引擎做了一個(gè)事情:

當(dāng)使用 set Interval()時(shí),僅當(dāng)沒(méi)有該定時(shí)器的任何其他代碼實(shí)例時(shí),才將定時(shí)器代碼添加到隊(duì)列中。

在1.7s處,func1在執(zhí)行,func2在隊(duì)列里等待執(zhí)行,func2就是該定時(shí)器的代碼實(shí)例,按照J(rèn)S引擎的處理,func3不會(huì)加入到事件隊(duì)列里,更別說(shuō)執(zhí)行了,這就導(dǎo)致出現(xiàn)了“丟幀”現(xiàn)象。而在圖中也可以注意到,func1執(zhí)行完畢,線程空閑了,func2就可以執(zhí)行了,這就使得func1和func2之間的執(zhí)行沒(méi)有時(shí)間間隔,這跟我們所預(yù)期的500ms產(chǎn)生一次結(jié)果是不同的。

而如果使用鏈?zhǔn)絪etTimeout調(diào)用,每次函數(shù)執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)新的定時(shí)器。第二個(gè)setTimeout()調(diào)用使用了 arguments.callee 來(lái)獲取對(duì)當(dāng)前執(zhí)行的函數(shù)的引用,并為其設(shè)置另外一個(gè)定時(shí)器。這樣做的好處是,在前一個(gè)定時(shí)器代碼執(zhí)行完之前,不會(huì)向隊(duì)列插入新的定時(shí)器代碼,確保不會(huì)有任何缺失的間隔。而且,它可以保證在下一次定時(shí)器代碼執(zhí)行之前,至少要等待指定的間隔,避免了連續(xù)的運(yùn)行。代碼如下所示

setTimeout(function(){
    //do something
    setTimeout(arguments.callee,interval);
},interval)

用setTimeout方法的話,上面假設(shè)的場(chǎng)景就發(fā)生了改變,如下圖所示,在0s處觸發(fā)click事件,click事件執(zhí)行,在0.2s處觸發(fā)定時(shí)器,0.7s處第一個(gè)函數(shù)func1加入到事件隊(duì)列,click事件執(zhí)行了1s,在1s處func1執(zhí)行,2s處func1執(zhí)行結(jié)束,第二個(gè)setTimeout定時(shí)器才被觸發(fā),0.5s后將函數(shù)func2加入隊(duì)列,此時(shí)隊(duì)列為空,func2開(kāi)始執(zhí)行,3.5s處func2執(zhí)行結(jié)束,又一個(gè)setTimeout定時(shí)器被觸發(fā),0.5s后將函數(shù)func3加入隊(duì)列,此時(shí)隊(duì)列為空,func3開(kāi)始執(zhí)行。。。

通過(guò)上面這個(gè)場(chǎng)景,我們能知道當(dāng)需要用定時(shí)器來(lái)設(shè)置一個(gè)操作重復(fù)執(zhí)行,并且這個(gè)操作需要執(zhí)行一定的時(shí)間,記得用setTimeout,不用setInterval!

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

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

相關(guān)文章

  • 結(jié)合源碼徹底理解 react事件機(jī)制原理 02 - 對(duì)于合成理解

    摘要:前言這是事件機(jī)制系列文章的第二篇對(duì)于合成的理解,咱們就來(lái)說(shuō)說(shuō)合成這個(gè)名詞。在給注冊(cè)事件的時(shí)候也是對(duì)兼容性做了處理??偨Y(jié)以上就是我對(duì)于合成這個(gè)名詞的理解,其實(shí)內(nèi)部還處理了很多,我只是略微簡(jiǎn)單的舉了幾個(gè)栗子。 showImg(https://segmentfault.com/img/bVbtvI3?w=1048&h=550); 前言 這是react事件機(jī)制系列文章的第二篇-對(duì)于合成的理解,...

    nihao 評(píng)論0 收藏0
  • 深度學(xué)習(xí)解決機(jī)器閱讀理解任務(wù)研究進(jìn)展

    摘要:深度學(xué)習(xí)近年來(lái)在中廣泛使用,在機(jī)器閱讀理解領(lǐng)域也是如此,深度學(xué)習(xí)技術(shù)的引入使得機(jī)器閱讀理解能力在最近一年內(nèi)有了大幅提高,本文對(duì)深度學(xué)習(xí)在機(jī)器閱讀理解領(lǐng)域的技術(shù)應(yīng)用及其進(jìn)展進(jìn)行了歸納梳理。目前的各種閱讀理解任務(wù)中完形填空式任務(wù)是最常見(jiàn)的類型。 關(guān)于閱讀理解,相信大家都不陌生,我們接受的傳統(tǒng)語(yǔ)文教育中閱讀理解是非常常規(guī)的考試內(nèi)容,一般形式就是給你一篇文章,然后針對(duì)這些文章提出一些問(wèn)題,學(xué)生回答這...

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

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

0條評(píng)論

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