setTimeout與setInterval

轉自:http://palmer.arkstack.cn/201...
一:平時簡單使用web

1.setTimeout延遲一段時間執行一次(only one)瀏覽器

setTimeout(function, milliseconds, param1, param2, ...)
clearTimeout() // 阻止定時器運行
setTimeout(function(){ alert("Hello"); }, 3000); // 3s後彈出

2.setInterval 每隔一段時間執行一次 (Many times)多線程

setInterval(function, milliseconds, param1, param2, ...)
 
 e.g.
 setInterval(function(){ alert("Hello"); }, 3000); // 每隔3s彈出

3.setTimeout和setInterval的延時最小間隔是4ms;在JavaScript中沒有任何代碼是馬上執行的,但一旦進程空閒就儘快執行。因此 setTimeout 仍是setInterval,設置的時間都是n毫秒被添加到隊列中,而不是過n毫秒後當即執行。
二:進程與線程異步

1.模擬一個場景
  • 有一個大型工廠
  • 工廠有若干車間,每次只能有一個車間做業
  • 每一個車間 有若干工人在流水線做業

那麼:async

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

在深刻一點:函數

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

再深刻:oop

  • 若是同時有多個車間做業,就是多進程
  • 若是一個車間裏有多個工人協同做業,就是多線程
  • 固然不一樣車間之間的工人也能夠有互相協做,就須要協調機制

三:JavaScript單線程spa

JavaScript這門語言的核心特徵,就是單線程(是指在JS引擎中負責解釋和執行JavaScript代碼的線程只有一個)。這和JavaScript最初設計是做爲一門GUI變成語言有關,最初用於瀏覽器端,單一線程控制GUI是很廣泛的作法。雖然JavaScript是單線程,當瀏覽器是多線程的!!!!!!!例如webkit或是Gecko引擎,可能有JavaScript引擎線程,界面渲染線程,瀏覽器事件觸發線程,Http請求線程,讀寫文件的線程。線程

四:同步異步
1.同步(synchronous):假如一個函數返回時,調用者就可以獲得預期結果(即拿到了預期的返回值或者看到了預期的效果)這就是同步函數設計

e.g.
alert('立刻能看到我拉');
console.log('也能立刻看到我哦');

2.異步(asynchronous):假如一個函數返回時,調用者不能獲得預期結果,須要經過必定手段才能得到,這就是異步函數。

e.g.
setTimeout(function() {
    // 過一段時間才能執行我哦
}, 1000);

五:異步構成要素

一個異步過程一般是這樣的:主線程發起一個異步請求,相應的工做線程(好比瀏覽器的其餘線程)接受請求並告知主線程已收到(異步函數返回);主線程能夠繼續執行 後面代碼,同時工做線程執行異步任務,工做線程完成工做號,告知主線程;主線程收到通知後,執行必定的動做(調用回調函數)

六:通訊機制

異步過程的通訊機制:工做線程將消息放到消息隊列,主線程經過事件循環過程去取消息

七:事件循環Event Loop

主線程(js線程)只會作一件事,就是從消息隊列裏面取消息,執行消息,再取消息,再執行。消息隊列爲空時,就會等待直到消息隊列變成非空。只有當前的消息執行結束,纔會去取下一個消息。這種機制就叫作事件循環機制Event Loop,取一個消息並執行的過程叫作一次循環

圖片描述

工做線程是生產者,主線程是消費者。工做線程執行異步任務,執行完成後把對應額回調函數封裝成一條消息放到消息隊列中;主線程不斷地從消息隊列中取消息並執行。當消息隊列爲空時,主線程阻塞,直到消息隊列再次非空。

八:setTimeOut(function,0)發生了什麼

setTimeOut的function的任務異步執行,0不表明當即執行,而是將任務推到消息隊列的最後,再由主線程的事件循環調用。
setTimeOut的最小時間不是0ms而是4ms

九:setInterval缺點

定時器指定的時間間隔,表示的是什麼時候將定時器的代碼添加到消息隊列,而不是什麼時候執行代碼,因此真正什麼時候執行代碼的時間是不能保證的。取決於什麼時候被主線程的事件循環取到,並執行。

setInterval(function, N)

上面代碼意味着,每隔N秒把function事件推到消息隊列中,何時執行,就不知道了

圖片描述

上圖可見,setInterval每隔100ms往隊列中添加一個事件;100ms後,添加T1定時器代碼至隊列中,主線程中還有任務在執行,因此等待,some event執行結束後執行T1定時器代碼;又過了100ms,T2定時器被添加到隊列中,主線程還在執行T1代碼,因此等待;又過了100ms,理論上又要往隊列裏推一個定時器代碼,但因爲此時T2還在隊列中,因此T3不會被添加,結果就是此時被跳過;這裏咱們能夠看到,T1定時器執行結束後立刻執行了T2代碼,因此並無達到定時器的效果。

setInterval兩個缺點:

  • 使用setInterval時,某些間隔會被跳過
  • 可能多個定時器會連續執行

十:鏈式setTimeOut

setTimeout(function () {
    // 任務
    setTimeout(arguments.callee, interval);
}, interval)

在嚴格模式下,第5版ECMAScript(ES5)禁止使用arguments.callee()。當一個函數必須調用自身的時候,避免使用arguments.callee(),經過要麼給函數表達式一個名字,要麼使用一個函數聲明

上述函數每次執行的時候都會建立一個新的定時器,第二個setTimeOut使用了arguments.callee()獲取當前函數的引用,而且爲其設置另外一個定時器。在一個定時器執行完前,不會向隊列插入新的定時器(解決缺點一),保證定時器間隔(解決缺點二)

相關文章
相關標籤/搜索