定時器的工作原理,這里將用引用How JavaScript Timers Work中的例子來解釋定時器的工作原理,該圖為一個簡單版的原理圖。·
上圖中,左側數字代表時間,單位毫秒;左側文字代表某一個操作完成后,瀏覽器去詢問當前隊列中存在哪些正在等待執行的操作;藍色方塊表示正在執行的代碼塊;右側文字代表在代碼運行過程中,出現哪些異步事件。該圖大致流程如下:
- 程序開始時,有一個JS代碼塊開始執行,執行時長約為18ms,在執行過程中有3個異步事件觸發,其中包括一個setTimeout、鼠標點擊事件、setInterval
- 第一個setTimeout先運行,延遲時間為10ms,稍后鼠標事件出現,瀏覽器在事件隊列中插入點擊的回調函數,稍后setInterval運行,10ms到達之后,setTimeout向事件隊列中插入setTimeout的回調
- 當第一個代碼塊執行完成后,瀏覽器查看隊列中有哪些事件在等待,他取出排在隊列最前面的代碼來執行
- 在瀏覽器處理鼠標點擊回調時,setInterval再次檢查到到達延遲時間,他將再次向事件隊列中插入一個interval的回調,以后每隔指定的延遲時間之后都會向隊列中插入一個回調
- 后面瀏覽器將在執行完當前隊頭的代碼之后,將再次取出目前隊頭的事件來執行
這里只是對定時器的原理做一個簡單版的描述,實際的處理過程比這個復雜。
下面我們利用定時器實現一個簡單的隨機點名功能,代碼如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style> div{width: 300px;height: 100px;margin: 20px auto;font-size: 50px;text-align: center;line-height: 100px;} #btn{width: 200px;height: 40px;margin: 10px auto;background: red;color: #FFFFFF;font-size: 20px;text-align: center;cursor: pointer;display: block;} </style>
</head>
<body>
<div id="content">請點擊按鈕</div>
<input type="button" id="btn" value="開始">
<script>
var ocontent = document.getElementById("content"); var obtn = document.getElementById("btn"); var onoff = 1; //打開
var timer = null; //設置全局變量
var str = ["亞瑟","鬼谷子","鎧","橘右京","項羽","夢奇","白起","趙雲","李白","韓信","劉備","魯班七號","墨子","孫臏","周瑜","庄周","廉頗","程咬金","典韋","后羿","扁鵲","李元芳","張飛","劉禪","蘭陵王","達摩","曹操","鍾馗","高漸離","宮本武藏","呂布","嬴政","姜子牙","老夫子","狄仁傑","夏侯惇","關羽","哪吒","太乙真人","干將莫邪","成吉思汗","牛魔","百里守約","百里玄策","蘇烈","黃忠","諸葛亮","東皇太一","楊戩","后羿","孫悟空","張良","韓信","劉邦","達摩","馬可波羅","娜可露露","露娜","妲己","甄姬","虞姬","大喬","小喬","王昭君","貂蟬","羋月","阿珂","花木蘭","武則天","不知火舞","孫尚香","蔡文姬","安琪拉","鍾無艷","女蝸","雅典娜","艾琳"] obtn.onclick = function(){ if(onoff == 1){ //開始隨機點名
clearInterval(timer);//避免重復點擊按鈕出現bug
timer = setInterval(function(){ var randomNum = Math.round(Math.random()*(str.length-1)) ocontent.innerHTML = str[randomNum]; },10) onoff = 0; //"定位"到暫停功能
obtn.value = "就是你了" }else if(onoff == 0){ clearInterval(timer); onoff = 1; //暫停后需恢復到重新開始的功能
obtn.value = "繼續" } } </script>
</body>
</html>
效果截圖如下:
這個隨機點名功能實現起來相對容易,利用了定時器,設置了一個開關來控制開始和暫停。
另外我在另一篇隨筆中用定時器寫了一個倒計時功能,實現原理和這個類似,關鍵的兩個點是定時器和開關,(相比較而言,開關更難理解)附上地址:https://www.cnblogs.com/qiaowanze/p/11399260.html