SetTimeout划鸽、setInterval與ClearTimeout

一行贪、SetTimeout與ClearTimeout

setTimeout()方法設(shè)置一個定時器建瘫,該定時器在定時器到期后執(zhí)行一個函數(shù)或指定的一段代碼。每次定時器到期函數(shù)只執(zhí)行一次殷蛇。

句法

var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);
var timeoutID = scope.setTimeout(function[, delay]); 
var timeoutID = scope.setTimeout(code[, delay]);

參數(shù)

function
function是你想要在到期時間(delay毫秒)之后執(zhí)行的橄浓。

code
這是一個可選語法,你可以使用字符串而不是function在delay毫秒之后編譯和執(zhí)行字符串 (使用該語法是不推薦的匀们, 原因和使用 [eval()]一樣准给。eval() 函數(shù)會將傳入的字符串當(dāng)做 JavaScript 代碼進(jìn)行執(zhí)行露氮,是有安全風(fēng)險)。

delay
延遲的毫秒數(shù) (一秒等于1000毫秒)畔规,函數(shù)的調(diào)用會在該延遲之后發(fā)生叁扫。如果省略該參數(shù),delay取默認(rèn)值0沈跨,意味著“馬上”執(zhí)行兔综,或者盡快執(zhí)行。不管是哪種情況涧窒,實際的延遲時間可能會比期待的(delay毫秒數(shù)) 值長锭亏。

param1, ..., paramN
附加參數(shù),一旦定時器到期戴已,它們會作為參數(shù)傳遞給[function]锅减。

返回值

返回值timeoutID是一個正整數(shù),表示定時器的編號握联。這個值可以傳遞給clearTimeout來取消該定時器每瞒。

需要注意的是setTimeout()setInterval()共用一個編號池剿骨。技術(shù)上clearTimeoutclearInterval()可以互換。但是浓利,為了避免混淆荞膘,不要混用取消定時函數(shù)。

因此在同一個對象上(一個window或者worker)淘菩,setTimeout()或者setInterval()在后續(xù)的調(diào)用不會重用同一個定時器編號屠升。但是不同的對象使用獨立的編號池。

例子

var myVar;
 
function myFunction() {
    myVar = setTimeout(function(){ 
        alert("Hello") 
    }, 3000);
}
 
function myStopFunction() {
    clearTimeout(myVar);
}

上述myFunction函數(shù)3秒后alert警告信息汇在,myStopFunction清除定時器脏答。

setTimeout除了做定時器外還能干什么用?

非常多阿蝶,比如說:在處理DOM點擊事件的時候通常會產(chǎn)生冒泡羡洁,正常情況下首先觸發(fā)的是子元素的handler,再觸發(fā)父元素的handler辛蚊,如果我想讓父元素的handler先于子元素的handler執(zhí)行應(yīng)該怎么辦真仲?那就用setTimeout延遲子元素handler若干個毫秒執(zhí)行吧。問題是這個“若干個”毫秒應(yīng)該是多少飞蛹?可以是0灸眼。請看:

(function () {
    setTimeout(function () {
        alert(2);
    }, 0);

    alert(1);
})()  

會先彈出1,再彈出2霉囚。
setTimeout匕积,setInterval都存在一個最小延遲的問題闪唆,雖然你給的delay值為0,但是瀏覽器執(zhí)行的是自己的最小值票顾。HTML5標(biāo)準(zhǔn)是4ms帆调,但并不意味著所有瀏覽器都會遵循這個標(biāo)準(zhǔn),包括手機瀏覽器在內(nèi)含鳞,這個最小值既有可能小于4ms也有可能大于4ms芹务。在標(biāo)準(zhǔn)中,如果在setTimeout中嵌套一個setTimeout, 那么嵌套的setTimeout的最小延遲為10ms潜必。

不光是上述磁滚,其他任何你想要延遲執(zhí)行的函數(shù)都可以使用SetTimeout()宵晚。

關(guān)于"this"的問題

查看下面的例子:

let myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
    alert(arguments.length > 0 ? this[sProperty] : this);
};

myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"

setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds

后兩行myArray.myMethod函數(shù)傳遞給 setTimeout,到了定時時間晒他,this沒有指向逸贾,默認(rèn)指向window對象铝侵。并且沒有方法把 thisArg 傳遞給setTimeout。
可能的解決方案:
一個通用的方法是使用包裝函數(shù)

setTimeout(function(){myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
setTimeout(function(){myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds

或者箭頭函數(shù)

setTimeout(() => {myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
setTimeout(() => {myArray.myMethod('1')}, 2500); // prints "one" after 2.5 second

**注:JavaScript 1.8.5 引入了 Function.prototype.bind()方法狐赡,該方法允許顯式地指定函數(shù)調(diào)用時 this 所指向的值 疟丙。該方法可以幫助你解決 this 指向不確定的問題享郊。

let myArray = ['zero', 'one', 'two'];
myBoundMethod = (function (sProperty) {
    console.log(arguments.length > 0 ? this[sProperty] : this);
}).bind(myArray);

myBoundMethod(); // prints "zero,one,two" because 'this' is bound to myArray in the function
myBoundMethod(1); // prints "one"
setTimeout(myBoundMethod, 1000); // still prints "zero,one,two" after 1 second because of the binding
setTimeout(myBoundMethod, 1500, "1"); // prints "one" after 1.5 seconds

二、SetInterval()

句法

intervalID = window.setInterval(function展蒂,delay [温自,param1悼泌,param2,...]);
intervalID = window.setInterval(code隘世,delay);
  • intervalID是定時器編號,
  • function是必須重復(fù)調(diào)用的[函數(shù)]
  • code在替代語法中复斥,是表示要重復(fù)執(zhí)行的代碼的字符串械媒。
  • delaysetInterval()每次調(diào)用前必須等待的毫秒數(shù)(千分之一秒)。如果delay小于10痢虹,則使用的值將減小為10主儡。

實例:

var y=0;
var x = new Date().getTime();
var d=setInterval(a,500);
function a() {
    y++;
   sleep(1000);
    if(y>=4){
        clearInterval(d)
    }
console.log(new Date().getTime()-x);

}
function sleep(sleepTime){
    var start=new Date().getTime();
    while(true){
        if(new Date().getTime()-start>sleepTime){
            break;    
        }
    }
}

上述控制臺輸出為:


輸出結(jié)果.png

可以看出糜值,setInterval()函數(shù)并沒有每隔500ms運行一次sleep函數(shù)寂汇。因此使用setInterval()函數(shù)是有風(fēng)險的。

這里介紹一下荣恐,JS是一個單線程的解釋器累贤,因此一段時間內(nèi)只能執(zhí)行一段代碼。為了要控制執(zhí)行的代碼硼被,就有一個JS任務(wù)隊列渗磅。這些任務(wù)會按照將它們添加到隊列的順序執(zhí)行始鱼。如果函數(shù)執(zhí)行時間過長,setInterval()函數(shù)間隔時間過短医清,就會導(dǎo)致一些【函數(shù)】被忽略掉会烙。

一般來說筒捺,使用超時調(diào)用是模擬(可以使用遞歸系吭,即自己調(diào)用自己)間歇調(diào)用的一種最佳模式颗品,在開發(fā)環(huán)境下很少用間歇調(diào)用。

參考:https://developer.mozilla.org/zhCN/docs/Web/API/Window/setTimeout
http://www.reibang.com/p/fc9a08ca2c92

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蟆盹,一起剝皮案震驚了整個濱河市闺金,隨后出現(xiàn)的幾起案子败匹,更是在濱河造成了極大的恐慌讥巡,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抬驴,居然都是意外死亡布持,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門按傅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胧卤,你說我怎么就攤上這事唯绍。” “怎么了枝誊?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵况芒,是天一觀的道長。 經(jīng)常有香客問我侧啼,道長牛柒,這世上最難降的妖魔是什么堪簿? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮皮壁,結(jié)果婚禮上椭更,老公的妹妹穿的比我還像新娘蛾魄。我一直安慰自己虑瀑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布滴须。 她就那樣靜靜地躺著舌狗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扔水。 梳的紋絲不亂的頭發(fā)上痛侍,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音魔市,去河邊找鬼主届。 笑死,一個胖子當(dāng)著我的面吹牛待德,可吹牛的內(nèi)容都是我干的君丁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼将宪,長吁一口氣:“原來是場噩夢啊……” “哼绘闷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起较坛,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤印蔗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后燎潮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喻鳄,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年确封,在試婚紗的時候發(fā)現(xiàn)自己被綠了除呵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡爪喘,死狀恐怖颜曾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秉剑,我是刑警寧澤泛豪,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響诡曙,放射性物質(zhì)發(fā)生泄漏臀叙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一价卤、第九天 我趴在偏房一處隱蔽的房頂上張望劝萤。 院中可真熱鬧,春花似錦慎璧、人聲如沸床嫌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厌处。三九已至,卻和暖如春岁疼,著一層夾襖步出監(jiān)牢的瞬間阔涉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工五续, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留洒敏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓疙驾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親郭毕。 傳聞我的和親對象是個殘疾皇子它碎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

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