JavaScript中setInterval()和setTimeout()的用法及區(qū)別
一、setInterval()
1、setInterval() 是JavaScript的一個定時器函數,用于設置周期性的定時任務。它的語法如下:
setInterval(function, delay, param1, param2, …);
其中,function參數表示要執(zhí)行的函數,delay參數表示定時器的時間間隔(以毫秒為單位),param1, param2, …表示傳遞給函數的參數(可選)。
setInterval()會不斷地重復執(zhí)行指定的函數,直到被取消或頁面被卸載。每個時間間隔結束時,function函數都會被調用一次。例如,下面的代碼會每隔1秒鐘輸出一次當前時間:
setInterval(function() { const now = new Date(); console.log(now.toLocaleTimeString()); }, 1000);
二、setTimeout()
1、setTimeout也是一個定時器函數,它允許我們在指定的時間后執(zhí)行一次函數。
setTimeout(function, delay, arg1, arg2, …)
- 其中,function 是我們要執(zhí)行的函數,delay 是延遲的時間(以毫秒為單位),arg1、arg2 等是傳遞給函數的參數(可選)。
- setTimeout 返回一個唯一的標識符,我們可以使用 clearTimeout 函數來取消這個定時器。代碼如下:
// 延遲 1 秒后輸出 "Hello, world!" const timerId = setTimeout(() => { console.log("Hello, world!"); }, 1000); // 取消定時器 clearTimeout(timerId);
這段代碼定義了一個 setTimeout 定時器,它會在 1 秒后執(zhí)行一個函數,輸出字符串 “Hello,world!”。同時,它會將返回的計時器 ID 存儲在變量 timerId 中。 接下來的一行代碼調用了 clearTimeout 函數,并傳timerId。這個函數會取消之前設置的定時器,從而避免了執(zhí)行函數的操作。因此,這段代碼最終不會輸出任何內容。
三、setInterval()和setTimeout()的區(qū)別
setInterval() 和 setTimeout() 都是 JavaScript 中的定時器函數,但它們有以下幾個區(qū)別:
1. setInterval() 在延遲指定時間后重復執(zhí)行指定任務,直到被取消或頁面關閉。而 setTimeout() 在延遲指定時間后執(zhí)行指定任務,只執(zhí)行一次;
2. setInterval() 的執(zhí)行間隔時間是固定的,而 setTimeout() 可以動態(tài)調整延遲時間;
3. setInterval() 可能會存在累積性誤差,因為它的執(zhí)行時間是相對于上一次任務結束的時間計算的,如果執(zhí)行的任務耗時超過了指定的時間間隔,就會出現累積性誤差。而 setTimeout() 每次執(zhí)行都是相對于上一次任務開始的時間計算的,不存在累積性誤差;
4. setInterval() 可能會對性能產生影響,因為它會不斷地重復執(zhí)行指定任務,占用 CPU 資源。而 setTimeout() 只會在指定時間后執(zhí)行一次任務,對性能影響較小。
因此,一般情況下,如果我們需要周期性地執(zhí)行指定任務,就可以使用 setInterval();如果我們只需要在指定時間后執(zhí)行一次任務,就可以使用 setTimeout()。
四、注意事項
使用setInterval()時要注意以下幾點:
- delay參數的最小值是4毫秒,如果設置的值小于4毫秒,則會被強制轉換為4毫秒。
- setInterval()返回一個定時器ID,可以使用clearInterval()函數來取消定時器。
- 由于JavaScript是單線程的,因此如果function函數執(zhí)行的時間過長,可能會影響頁面的響應性能。因此,建議在編寫function函數時要盡量減少執(zhí)行時間。
補充:常見的面試題
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、追問 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);
存在錯誤的方式三
for (let i = 0; i < 5; i++) { setTimeout(function() { console.log(new Date, i); }, 1000); } console.log(new Date, i);//let,for循環(huán)外部訪問不到i
追問 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 的定時器時間 })(i); } setTimeout(function() { // 這里增加定時器,超時設置為 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()相當于實現鏈式操作 console.log(new Date, j); }, 1000*j )); // 這里修改 0~4 的定時器時間 })(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,否則代碼不會按預期 work }, 1000 * j); // 定時器的超時時間逐步增加 })); })(i); } Promise.all(tasks).then(() => { setTimeout(() => { console.log(new Date, i); }, 1000); // 注意這里只需要把超時設置為 1 秒 });
總結
到此這篇關于JavaScript中setInterval()和setTimeout()用法及區(qū)別的文章就介紹到這了,更多相關setInterval()和setTimeout()用法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript中三個等號和兩個等號的區(qū)別(== 和 ===)淺析
javascript中比較運算符'=='與'==='可能大家用的比較多,但是大家對他的區(qū)別不是很清楚,接下來小編給大家介紹下js中三個等號和兩個等號的區(qū)別(== 和 ===),感興趣的朋友可以參考下2016-09-09復制Input內容的js代碼_支持所有瀏覽器,修正了Firefox3.5以上的問題
今天作一個功能,有一個input,里邊有內容,點一下按鈕就復制里邊的內容到剪貼板2010-06-06