1. 程式人生 > >setTimeout和setInterval的區別

setTimeout和setInterval的區別

<span style="font-family: Tahoma, Helvetica, Arial, 宋體, sans-serif;">function click() { </span>
<span style="white-space:pre">	</span>// code block1... 
<span style="white-space:pre">	</span>setTimeout(function() { 
<span style="white-space:pre">		</span>// process ... 
<span style="white-space:pre">	</span>}, 200); 
<span style="white-space:pre">	</span>// code block2 
} 
假設我們給一個button的onclick事件綁定了此方法, 當我們按下按鈕後, 肯定先執行block1的內容, 然後執行到setTimeout的地方, setTimeout會告訴瀏覽器說, "200ms後我會插一段要執行的程式碼給你的佇列中", 瀏覽器當然答應了(注意插入程式碼並不意味著立馬執行), setTimeout程式碼執行後, 緊跟其後的block2程式碼開始執行, 這裡就開始說明問題了, 如果block2的程式碼執行時間超過200ms, 那結果會是如何? 或許按照你之前的理解, 會理所當然的認為200ms一到, 你的process程式碼會立馬執行...事實是, 在block2執行過程中(執行了200ms後)process程式碼被插入程式碼佇列, 但一直要等click方法執行結束, 才會執行process程式碼段, 從程式碼佇列上看process程式碼是在click後面的, 再加上js以單執行緒方式執行, 所以應該不難理解. 如果是另一種情況, block2程式碼執行的時間<200ms, setTimeout在200ms後將process程式碼插入到程式碼佇列, 而那時執行執行緒可能已經處於空閒狀態了(idle), 那結果就是200ms後, process程式碼插入佇列就立馬執行了, 就讓你感覺200ms後, 就執行了. 

再看看setInterval 
這裡可能會存在兩個問題: 
1.時間間隔或許會跳過 
2.時間間隔可能<定時呼叫的程式碼的執行時間 
function click() { 
// code block1... 
setInterval(function() { 
// process ... 
}, 200); 
// code block2 
} 
<p style="margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-bottom: 5px; font-size: 14px; font-family: Tahoma, Helvetica, Arial, 宋體, sans-serif; line-height: 25.2000007629395px; background-color: rgb(247, 252, 255);">比如onclick要300ms執行完, block1程式碼執行完, 在5ms時執行setInterval, 以此為一個時間點, 在205ms時插入process程式碼, click程式碼順利結束, process程式碼開始執行(相當於圖中的timer code), 然而process程式碼也執行了一個比較長的時間, 超過了接下來一個插入時間點405ms, 這樣程式碼佇列後又插入了一份process程式碼, process繼續執行著, 而且超過了605ms這個插入時間點, 下面問題來, 可能你還會認為程式碼佇列後面又會繼續插入一份process程式碼...真實的情況是,由於程式碼佇列中已經有了一份未執行的process程式碼, 所以605ms這個插入時間點將會被"無情"的跳過, 因為js引擎只允許有一份未執行的process程式碼, 說到這裡不知道您是不是會豁然開朗呢...</p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 5px; padding-bottom: 5px; font-size: 14px; font-family: Tahoma, Helvetica, Arial, 宋體, sans-serif; line-height: 25.2000007629395px; background-color: rgb(247, 252, 255);">為了這種情況你可以用一種更好的程式碼形式</p><pre name="code" class="javascript">setTimeout(function(){ 
//processing 
setTimeout(arguments.callee, interval); 
}, interval); 
<span style="font-family: Tahoma, Helvetica, Arial, 宋體, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(247, 252, 255);">這個估計稍微想一下, 就明白其中的好處了, 這樣就不會產生時間點被跳過的問題內容就到這裡, 希望能有所幫助, 可能我表達的不是很清楚如果覺得自己英語基礎不錯可以直接看</span>