iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 29
0

瀏覽器提供的計時器功能有 setTimeoutsetInterval二種,我們用它們來延遲一段時間才執行一段程式。

計時器並不是 JavaScript 的功能,而是隸屬於window物件底下的方法,因此在撰寫程式碼時,可省略window物件名稱。會這樣說是因為在 Node.js 環境下也有計時器的功能,方法的名稱也是一樣,但作用和瀏覽器有一些不一樣的地方。這裡我們專注在探討瀏覽器的計時器。

var timeoutID = setTimeout(function(){}, 1000);
var intervalID = setInterval(function(){}, 1000)

clearTimeout(timeoutID);
clearInterval(intervalID);

建立計時器的方式都是先呼叫方法,再代入一個函式,以及一個時間,時間是以毫秒為單位,1秒鐘就是1000毫秒。

提到計時器一定要和前一篇文章的 event loop 一起來看。

console.log("start");
(function(){
	console.log("bar");
	setTimeout(function(){
		console.log("foo");
	}, 0);
})();
console.log("end");

在上面的範例中,或許有人會認為 console 中的訊息是:

"start"
"bar"
"foo"
"end"

立即函式跑完"bar"之後,因為setTimeout延遲的時間是0,所以立刻執行。事實上 console 訊息卻是這樣:

"start"
"bar"
"end"
"foo"

從 event loop 模型來看,整段程式在執行時正佔據 JavaScript call stack,setTimeout事件會被瀏覽器接手,在時間到期時,將函式丟到 task queue 裡,在這裡的任務一定會等到 call stack 的任務完全清空後,才由 event loop 將排第一個的任務移到 call stack 執行。

"start", "bar", "end"會先執行完,然後才由 event loop 從 task queue 裡把"foo"叫到 call stack。

setTimeoutsetInterval都會回傳一個計時器ID,我們可以使用clearTimeoutclearInterval二個方法清除計時器,只要代入ID值,但是要在計時器有效的狀態。也就是說一旦setTimeout時間到把函式排進 task queue 之後,它就功成身退,這時也沒有必要再清除它。

雖然setTimeoutsetInterval都會將函式排進 task queue 裡,但是它們有不同的地方。

setInterval的計時器在設定的時間到的時候,會將函式排進 task queue 裡,但是如果 task queue 裡已經有上一次計時器排入的任務,setInterval就不會再安排新的任務進去,繼續它的計時。如果是setTimeout在函式裡又再回呼自己的話,還是會將函式排入 task queue。


上一篇
Day 28: 深入事件迴圈
下一篇
Day 30: DOM 和事件
系列文
JavaScript 忍者的修練--從下忍進階到中忍30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言