setInterval與setTimeout

在本身用canvas畫一個時鐘時,畫秒鐘用的是利用圖片將重複的線條遮住,可是會出現有兩個秒鐘線條同時存在,纔想起setInterval有那麼個坑,查了點資料,記錄下,如有不對的或者未寫到的點,還請你們指出,謝謝^_^
  • 在此以前先科普下這個學習點

進程與線程的區別

借用阮一峯大大借用的比喻,實現一個小實例:javascript

  • 有一個大型工廠
  • 工廠裏有若干車間,每次只能有一個車間在做業
  • 每一個車間裏有若干房間,有若干工人在流水線做業

那麼:java

  • 一個工廠對應的就是計算機的一個CPU,平時講的多核就表明多個工廠
  • 每一個工廠裏的車間,就是進程,意味着同一時刻一個CPU只運行一個進程,其他進程在怠工
  • 這個運行的車間(進程)裏的工人,就是線程,能夠有多個工人(線程)協同完成一個任務
  • 車間(進程)裏的房間,表明內存。

再深刻點:webpack

  • 車間(進程)裏工人能夠隨意在多個房間(內存)之間走動,意味着一個進程裏,多個線程能夠共享內存
  • 部分房間(內存)有限,只容許一個工人(線程)使用,此時其餘工人(線程)要等待
  • 房間裏有工人進去後上鎖,其餘工人須要等房間(內存)裏的工人(線程)開鎖出來後,才能才進去,這就是互斥鎖(Mutual exclusion,縮寫 Mutex)
  • 有些房間只能容納部分的人,意味着部份內存只能給有限的線程

再再深刻:web

  • 若是同時有多個車間做業,就是多進程
  • 若是一個車間裏有多個工人協同做業,就是多線程
  • 固然不一樣車間之間的工人也能夠有相互協做,就須要協調機制
感受一會兒就記住了這二者的概念及區別

1.setTimeout

  • setTimeout()用來指定某個函數或字符串在指定的毫秒數以後執行;它會返回一個整數,表示定時器的編號,這個值能夠傳遞給clearTimeout()用來清除定時器
/* 一秒鐘後在控制檯上打印出111 */
<script>
    setTimeout(function() {
        console.log(111);
    }, 1000)
</script>
  • 也能夠寫成字符串參數的形式,但這種形式會形成javascript引擎兩次解析,下降性能(1.引擎內部使用eval()函數,將字符串轉爲代碼;2.代碼執行的解析)
<script>
    setTimeout('console.log(111)', 1000)
</script>

2.在IE瀏覽器中使用定時器存在部分小問題:

  • IE9瀏覽器只容許setTimeout有兩個參數,不支持更多的參數,會在控制檯輸出NaN面試

    • 能夠使用IIFE來進行參數的傳遞
setTimeout((function(x, y) {
    console.log(x+y);
})(1,2), 1000)
  • IE8瀏覽器不容許向定時器中傳遞事件對象eventcanvas

    • 能夠將事件對象中的某些屬性保存在變量中傳遞進去
div.onclick = function(e) {
    e = e || event;
    let type = e.type;
    setTimeout(function(e) {
        console.log(e.type);  /* 報錯 */
        console.log(type);  /* click */
    }, 1000)
}

3.setInterval

  • setInterval指定某個任務每隔一段時間就執行一次,也就是無限次的定時執行
HTML5標準規定,setTimeout的最短期間隔是4ms;setInterval的最短間隔時間是10ms,因此,小於了最短的時間間隔會被調整到最短期間隔
  • 使用setInterval()時,定時器代碼可能在代碼再次被添加到隊列以前尚未完成執行,致使定時器代碼連續執行了屢次,但之間沒有任何停頓。javascript引擎的解決方式就是:使用setInterval()時,僅當沒有該定時器的任何其餘代碼實例時,纔將定時器代碼添加到執行隊列中,確保定時器代碼加入到隊列中的最小時間間隔爲指定間隔
但這也會致使兩個問題:1.某些間隔被跳過2.多個定時器的代碼執行之間的間隔可能比預期的小
  • 以下圖:
clipboard.png

4.鏈式setTimeout

  • 使用鏈式setTimeout來解決我畫時鐘的那個問題
setTimeout(function fn() {
    console.log(111);
    setTimeout(fn, 1000);
}, 1000)
  • 使用鏈式模式調用setTimeout(),函數執行的時候都會建立一個新的定時器。第二個setTimeout()調用當前執行的函數,併爲其設置另一個定時器。使得在前一個定時器代碼執行完以前,不會向隊列插入新的定時器代碼,確保不會有任何缺失的間隔。並且,它能夠保證在下一次定時器代碼執行以前,至少要等待指定的間隔,避免了連續的運行
正在努力學習中,若對你的學習有幫助,留下你的印記唄(點個贊咯^_^)
相關文章
相關標籤/搜索