JavaScript定時器setTimeout、setInterval使用詳解
定時器:按我個人理解來說就是固定某個時間后,時間到了,就提醒我時間到了。
程序中的定時器:相當于倒計時,也相當于計時器。作用是在設(shè)定的某個時間后,執(zhí)行特定的方法。
我們先來了解一下setTimeout定時器,他的特點就是只能用一次,也稱為一次性定時器。
setTimeout( func, time, argument1, argument2, .... );
語法解析:
1、func:固定時間后執(zhí)行的方法
2、time:設(shè)置固定的時間-按毫秒計算
3、argument:傳入方法的參數(shù)
案例:?? ?setTimeout(function(name,gender){ ?? ??? ?console.log(name + " is " + gender); ?? ?}, 1000, "Tom", "boy");簡寫:
?? ?setTimeout((name,gender) => { ?? ??? ?console.log(name + " is " + gender); ?? ?}, 1000, "Tom", "boy");案例解析:
開啟了一個一次性定時器,1秒后執(zhí)行我給定的函數(shù)。
接著看看 setInterval定時器,他的特點就是可以重復執(zhí)行給定的函數(shù)。
console.log("1 ===>");
setTimeout(function(name,gender){
console.log(name + " is " + gender);
}, 1000, "Tom", "boy");
console.log("2 ===>");
執(zhí)行結(jié)果:
> "1 ===>"
> "2 ===>"
> "Tom is boy"接下來就開始圈重點了:
定時器概念了解了,也會造定時器了,那這個定時器什么時候調(diào)用呢,因為我們的 javaScript代碼是從上到下,逐行執(zhí)行,那到了定時器這行我們的進程會不會等定時器執(zhí)行完了再執(zhí)行定時器后面的代碼呢?答案是不會等!
遇到定時器,會將定時器加入到任務(wù)隊列中(宏任務(wù)),等所有代碼執(zhí)行完了,程序會看一下隊列中還有什么沒有完成的 ,如果有沒完成的,就執(zhí)行一下。
這樣說可能有點抽象,看下案例好了。
console.log("1 ===>");
setTimeout(function(name,gender){
console.log(name + " is " + gender);
}, 1000, "Tom", "boy");
console.log("2 ===>");
執(zhí)行結(jié)果:
> "1 ===>"
> "2 ===>"
> "Tom is boy"注意:任務(wù)隊列里的執(zhí)行順序是按先來后到的
接下來再深入理解一下,我們先思考一個問題,一次性定時器和重復性定時器區(qū)別在哪,不可能就只是調(diào)一次和調(diào)多次這么簡單吧。
提醒:接下來的內(nèi)容比較重要,有點抽象但需要理解透徹
案例:假設(shè)我們需要每隔一秒控制臺輸出一句話。
結(jié)合我們本文的學習,給出思路:
1、一次性定時器的函數(shù)里再調(diào)定時器,形成循環(huán)。
2、開啟一個重復性定時器
編寫實現(xiàn)代碼:
思路1:
setTimeout(function run(name,gender){
console.log(" hello");
setTimeout(run,1000);
}, 1000);
思路2:
setInterval(()=>{
console.log("hello")
},1000);看到這大家可能會不禁感嘆,就這?就這?這哪復雜了,逗我呢。
那不妨思考一下,第二個一次性定時器啥時候開始執(zhí)行呢?第三個呢?第n個呢?程序運行的第n秒?
那我稍微改造一下剛剛的案例好了
let start = Date.now(); // 程序一運行的時間
let times = []; // 用來記錄運行時間的數(shù)組
let sTime = setInterval(()=>{
times.push(Date.now() - start); // 記錄下執(zhí)行時間
if (start + 5000 < Date.now()) {
console.log(times);
}
},1000);接著可以思考一下輸出的結(jié)果是什么。
然后再來思考重復性定時器,第二次函數(shù)調(diào)用是啥時候執(zhí)行呢?第三個呢?第n個呢?
再稍微改造一下好了
let start = Date.now(); // 程序一運行的時間
let times = []; // 用來記錄運行時間的數(shù)組
let sTime = setInterval(()=>{
times.push(Date.now() - start); // 記錄下執(zhí)行時間
if (start + 5000 < Date.now()) {
console.log(times);
}
},1000);好了,留些時間思考一下…
思考好了嗎,好了的話一起揭曉一下答案吧。
第一種情況:
> "1 ===>"
> "2 ===>"
> "1 ===>"
> "2 ===>"第二種情況:
> Array [1001, 2003, 3003, 4000, 5000, 6000]分析:
情況1:思考這個問題就可 -> 輸出 "1 ===>" 之后我開啟了另一個定時器,此時是不是應(yīng)該再輸出"1 ===>"?然后就進入了定時器循環(huán),結(jié)果一直只有"1 ===>"?
結(jié)合我們的結(jié)果,可以發(fā)現(xiàn)下一個定時器是什么時候開的?沒錯,執(zhí)行完第一個定時器函數(shù)內(nèi)的代碼后再執(zhí)行的。
情況2:根據(jù)時間的間隔很容易知道時間就是1秒上下幾毫秒,所以下一個定時器是第一個定時器時間結(jié)束后立即開啟的。
這就是他們兩個比較靠底層的區(qū)別。
總結(jié)的話就留給大家自己總結(jié)吧,畢竟一千個讀者就會有一千個讀者(哈哈,開個玩笑,說句可能像話的話??)。
現(xiàn)在我們已經(jīng)大致了解了定時器以及觸發(fā)時間,那么會造定時器了不會取消就有點說不過去了,下面一起看看怎么取消定時器。
let timerId1 = setTimeout(...); clearTimeout(timerId1); // 取消一次性定時器,timeId1 是唯一且必傳參數(shù) let timerId2 = setInterval(...); clearInterval(timerId2)。 // 取消重復定時器,timeId2 是唯一且必傳參數(shù)
注意:定時器開啟了一定要關(guān)閉,要做到有始有終,不然會一直消耗內(nèi)存,到時候就就很容易程序崩潰。
還有一個留最后講的,因為比較細節(jié)。
下面我們來看個案例
let start = Date.now();
let times = [];
setTimeout(function run() {
times.push(Date.now() - start); // 保存前一個調(diào)用的延時
if (start + 50 < Date.now()) console.log(times); // 100 毫秒之后,顯示延時信息
else setTimeout(run); // 否則重新調(diào)度
});
結(jié)果:
> Array [1, 2, 4, 5, 9, 13, 18, 22, 27, 32, 36, 42, 46, 50, 55]let start = Date.now(); // 程序一運行的時間
let times = []; // 用來記錄運行時間的數(shù)組
let sTime = setInterval(()=>{
times.push(Date.now() - start); // 記錄下執(zhí)行時間
if (start + 50 < Date.now()) {
console.log(times);
clearInterval(sTime); // 清除定時器
}
});
結(jié)果:
> Array [1, 2, 3, 4, 8, 13, 16, 20, 25, 28, 32, 36, 40, 44, 48, 53]感興趣的同學可以分別思考一下這兩組數(shù)組的規(guī)律,然后再往下看
好了,這就不賣關(guān)子了,直接把結(jié)論告訴大家吧
瀏覽器會將 setTimeout 或 setInterval 的五層或更多層嵌套調(diào)用(調(diào)用五次之后)的最小延時限制在 4ms。這是歷史遺留問題。
最后,大家拷貝案例執(zhí)行的時候,運行的結(jié)果很大概率和我這個結(jié)果不一樣,影響的因素有瀏覽器版本、類型等等問題。不過這也不影響結(jié)論是正確的
總結(jié)
到此這篇關(guān)于JavaScript定時器setTimeout、setInterval使用的文章就介紹到這了,更多相關(guān)定時器setTimeout、setInterval使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js取兩個數(shù)組的交集|差集|并集|補集|去重示例代碼
求兩個集合的補集、交集、差集、并集等等在實際應(yīng)用中經(jīng)常會使用到,下面與大家分享下具體的實現(xiàn)代碼,感興趣的朋友可以參考下,希望對大家有所幫助2013-08-08
javascript實現(xiàn)查找數(shù)組中最大值方法匯總
本文給大家匯總了一下使用javascript實現(xiàn)查找數(shù)組中最大最小值的一些方法,非常的簡單實用,有需要的小伙伴可以來參考下。2016-02-02
js實現(xiàn)QQ面板拖拽效果(慕課網(wǎng)DOM事件探秘)(全)
這篇文章主要為大家詳細介紹了QQ面板拖拽效果,探秘慕課網(wǎng)DOM事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
解決axios會發(fā)送兩次請求,有個OPTIONS請求的問題
這篇文章主要介紹了解決axios會發(fā)送兩次請求,有個OPTIONS請求的問題,需要的朋友可以參考下2018-10-10
js 使用ajax設(shè)置和獲取自定義header信息的方法小結(jié)
這篇文章主要介紹了js 使用ajax設(shè)置和獲取自定義header信息的方法,結(jié)合實例形式總結(jié)分析了js 使用ajax自定義設(shè)置和獲取header響應(yīng)信息相關(guān)操作技巧與使用注意事項,需要的朋友可以參考下2020-03-03
解決bootstrap中使用modal加載kindeditor時彈出層文本框不能輸入的問題
這篇文章主要介紹了解決bootstrap中使用modal加載kindeditor時彈出層文本框不能輸入的問題,需要的朋友可以參考下2017-06-06
uniapp中微信小程序與H5相互跳轉(zhuǎn)以及傳參詳解(webview)
在單位做項目的時候碰到一個需求,需要從微信小程序跳轉(zhuǎn)到H5頁面,下面這篇文章主要給大家介紹了關(guān)于uniapp中微信小程序與H5相互跳轉(zhuǎn)以及傳參的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-08-08

