JavaScript中setInterval()和setTimeout()的用法及區(qū)別
一、setInterval()
1、setInterval() 是JavaScript的一個(gè)定時(shí)器函數(shù),用于設(shè)置周期性的定時(shí)任務(wù)。它的語(yǔ)法如下:
setInterval(function, delay, param1, param2, …);
其中,function參數(shù)表示要執(zhí)行的函數(shù),delay參數(shù)表示定時(shí)器的時(shí)間間隔(以毫秒為單位),param1, param2, …表示傳遞給函數(shù)的參數(shù)(可選)。
setInterval()會(huì)不斷地重復(fù)執(zhí)行指定的函數(shù),直到被取消或頁(yè)面被卸載。每個(gè)時(shí)間間隔結(jié)束時(shí),function函數(shù)都會(huì)被調(diào)用一次。例如,下面的代碼會(huì)每隔1秒鐘輸出一次當(dāng)前時(shí)間:
setInterval(function() { const now = new Date(); console.log(now.toLocaleTimeString()); }, 1000);
二、setTimeout()
1、setTimeout也是一個(gè)定時(shí)器函數(shù),它允許我們?cè)谥付ǖ臅r(shí)間后執(zhí)行一次函數(shù)。
setTimeout(function, delay, arg1, arg2, …)
- 其中,function 是我們要執(zhí)行的函數(shù),delay 是延遲的時(shí)間(以毫秒為單位),arg1、arg2 等是傳遞給函數(shù)的參數(shù)(可選)。
- setTimeout 返回一個(gè)唯一的標(biāo)識(shí)符,我們可以使用 clearTimeout 函數(shù)來(lái)取消這個(gè)定時(shí)器。代碼如下:
// 延遲 1 秒后輸出 "Hello, world!" const timerId = setTimeout(() => { console.log("Hello, world!"); }, 1000); // 取消定時(shí)器 clearTimeout(timerId);
這段代碼定義了一個(gè) setTimeout 定時(shí)器,它會(huì)在 1 秒后執(zhí)行一個(gè)函數(shù),輸出字符串 “Hello,world!”。同時(shí),它會(huì)將返回的計(jì)時(shí)器 ID 存儲(chǔ)在變量 timerId 中。 接下來(lái)的一行代碼調(diào)用了 clearTimeout 函數(shù),并傳timerId。這個(gè)函數(shù)會(huì)取消之前設(shè)置的定時(shí)器,從而避免了執(zhí)行函數(shù)的操作。因此,這段代碼最終不會(huì)輸出任何內(nèi)容。
三、setInterval()和setTimeout()的區(qū)別
setInterval() 和 setTimeout() 都是 JavaScript 中的定時(shí)器函數(shù),但它們有以下幾個(gè)區(qū)別:
1. setInterval() 在延遲指定時(shí)間后重復(fù)執(zhí)行指定任務(wù),直到被取消或頁(yè)面關(guān)閉。而 setTimeout() 在延遲指定時(shí)間后執(zhí)行指定任務(wù),只執(zhí)行一次;
2. setInterval() 的執(zhí)行間隔時(shí)間是固定的,而 setTimeout() 可以動(dòng)態(tài)調(diào)整延遲時(shí)間;
3. setInterval() 可能會(huì)存在累積性誤差,因?yàn)樗膱?zhí)行時(shí)間是相對(duì)于上一次任務(wù)結(jié)束的時(shí)間計(jì)算的,如果執(zhí)行的任務(wù)耗時(shí)超過(guò)了指定的時(shí)間間隔,就會(huì)出現(xiàn)累積性誤差。而 setTimeout() 每次執(zhí)行都是相對(duì)于上一次任務(wù)開(kāi)始的時(shí)間計(jì)算的,不存在累積性誤差;
4. setInterval() 可能會(huì)對(duì)性能產(chǎn)生影響,因?yàn)樗鼤?huì)不斷地重復(fù)執(zhí)行指定任務(wù),占用 CPU 資源。而 setTimeout() 只會(huì)在指定時(shí)間后執(zhí)行一次任務(wù),對(duì)性能影響較小。
因此,一般情況下,如果我們需要周期性地執(zhí)行指定任務(wù),就可以使用 setInterval();如果我們只需要在指定時(shí)間后執(zhí)行一次任務(wù),就可以使用 setTimeout()。
四、注意事項(xiàng)
使用setInterval()時(shí)要注意以下幾點(diǎn):
- delay參數(shù)的最小值是4毫秒,如果設(shè)置的值小于4毫秒,則會(huì)被強(qiáng)制轉(zhuǎn)換為4毫秒。
- setInterval()返回一個(gè)定時(shí)器ID,可以使用clearInterval()函數(shù)來(lái)取消定時(shí)器。
- 由于JavaScript是單線程的,因此如果function函數(shù)執(zhí)行的時(shí)間過(guò)長(zhǎng),可能會(huì)影響頁(yè)面的響應(yīng)性能。因此,建議在編寫(xiě)function函數(shù)時(shí)要盡量減少執(zhí)行時(shí)間。
補(bǔ)充:常見(jiàn)的面試題
1、分析輸出
for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(new Date, i); }, 1000); } console.log(new Date, i);
輸出:
5->5,5,5,5,5(->代表1s)
2018-08-14T08:20:05.694Z 5
2018-08-14T08:20:06.696Z 5
2018-08-14T08:20:06.697Z 5
2018-08-14T08:20:06.697Z 5
2018-08-14T08:20:06.698Z 5
2018-08-14T08:20:06.698Z 5
2、追問(wèn) 1:閉包期望代碼的輸出變成:5 -> 0,1,2,3,4,該怎么改造代碼?
方式一:
for (var i = 0; i < 5; i++) { (function(j) { // j = i setTimeout(function() { console.log(new Date, j); }, 1000); })(i); } console.log(new Date, i);
方式二:
for (var i = 0; i < 5; i++) { setTimeout( (function (j) { // j = i return function () { console.log(new Date, j); } })(i), 1000); } console.log(new Date, i);
存在錯(cuò)誤的方式三
for (let i = 0; i < 5; i++) { setTimeout(function() { console.log(new Date, i); }, 1000); } console.log(new Date, i);//let,for循環(huán)外部訪問(wèn)不到i
追問(wèn) 2:ES6
如果期望代碼的輸出變成 0 -> 1 -> 2 -> 3 -> 4 -> 5,并且要求原有的代碼塊中的循環(huán)和兩處 console.log 不變,該怎么改造代碼?
方式一:
for (var i = 0; i < 5; i++) { (function(j) { setTimeout(function() { console.log(new Date, j); }, 1000 * j); // 這里修改 0~4 的定時(shí)器時(shí)間 })(i); } setTimeout(function() { // 這里增加定時(shí)器,超時(shí)設(shè)置為 5 秒 console.log(new Date, i); }, 1000 * i);
方式二:promise
var p= Promise.resolve() for (var i = 0; i < 5; i++) { (function(j){ p=p.then(setTimeout(function() {//p=p.then()相當(dāng)于實(shí)現(xiàn)鏈?zhǔn)讲僮? console.log(new Date, j); }, 1000*j )); // 這里修改 0~4 的定時(shí)器時(shí)間 })(i) } setTimeout(function(){ p.then(console.log(new Date, i)) }, 1000*i) ;
方式二:promise.all
const tasks = []; for (var i = 0; i < 5; i++) { // 這里 i 的聲明不能改成 let,如果要改該怎么做? ((j) => { tasks.push(new Promise((resolve) => { setTimeout(() => { console.log(new Date, j); resolve(); // 這里一定要 resolve,否則代碼不會(huì)按預(yù)期 work }, 1000 * j); // 定時(shí)器的超時(shí)時(shí)間逐步增加 })); })(i); } Promise.all(tasks).then(() => { setTimeout(() => { console.log(new Date, i); }, 1000); // 注意這里只需要把超時(shí)設(shè)置為 1 秒 });
總結(jié)
到此這篇關(guān)于JavaScript中setInterval()和setTimeout()用法及區(qū)別的文章就介紹到這了,更多相關(guān)setInterval()和setTimeout()用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Js中setTimeout()和setInterval() 何時(shí)被調(diào)用執(zhí)行的用法
- JavaScript定時(shí)器setTimeout()和setInterval()詳解
- 精解window.setTimeout()&window.setInterval()使用方式與參數(shù)傳遞問(wèn)題!
- setInterval()和setTimeout()的用法和區(qū)別示例介紹
- setTimeout()與setInterval()方法區(qū)別介紹
- JavaScript setInterval()與setTimeout()計(jì)時(shí)器
- JavaScript中定時(shí)器setTimeout()和setInterval()的用法
相關(guān)文章
js實(shí)現(xiàn)編輯div節(jié)點(diǎn)名稱的方法
這篇文章主要介紹了js實(shí)現(xiàn)編輯div節(jié)點(diǎn)名稱的方法,可實(shí)現(xiàn)針對(duì)div節(jié)點(diǎn)名稱的編輯及樣式的選擇效果,并且分別針對(duì)IE與FF瀏覽器的樣式進(jìn)行了選擇與控制,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12輕量級(jí)的原生js日歷插件calendar.js使用指南
網(wǎng)頁(yè)上的原生js日歷代碼,鼠標(biāo)點(diǎn)擊文字提示處,會(huì)顯示一個(gè)帶年月日的日歷窗口,可調(diào)整年份、月份、選擇日期等,用在網(wǎng)頁(yè)上方便大家選擇日期,提高用戶體驗(yàn)。各大瀏覽器都能正常運(yùn)行,有需要的小伙伴可以參考下。2015-04-04javascript制作照片墻及制作過(guò)程中出現(xiàn)的問(wèn)題
這篇文章主要介紹了javascript制作照片墻及制作過(guò)程中出現(xiàn)的問(wèn)題,感興趣的朋友可以參考一下2016-04-04JavaScript中三個(gè)等號(hào)和兩個(gè)等號(hào)的區(qū)別(== 和 ===)淺析
javascript中比較運(yùn)算符'=='與'==='可能大家用的比較多,但是大家對(duì)他的區(qū)別不是很清楚,接下來(lái)小編給大家介紹下js中三個(gè)等號(hào)和兩個(gè)等號(hào)的區(qū)別(== 和 ===),感興趣的朋友可以參考下2016-09-09復(fù)制Input內(nèi)容的js代碼_支持所有瀏覽器,修正了Firefox3.5以上的問(wèn)題
今天作一個(gè)功能,有一個(gè)input,里邊有內(nèi)容,點(diǎn)一下按鈕就復(fù)制里邊的內(nèi)容到剪貼板2010-06-06js實(shí)現(xiàn)字符全排列算法的簡(jiǎn)單方法
下面小編就為大家?guī)?lái)一篇js實(shí)現(xiàn)字符全排列算法的簡(jiǎn)單方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05