理解javascript定時器中的單線程,javascript定時器

來源:互聯網
上載者:User

理解javascript定時器中的單線程,javascript定時器

一、JavaScript 引擎是單線程的

可以從下面的代碼中看到,第一個用setTimeout中的代碼是死迴圈,由於是單線程,下面的兩個定時器就沒機會執行了。

<script type="text/javascript"> setTimeout( function(){ while(true){} } , 100);  setTimeout( function(){ alert('你好!setTimeout'); } , 200);  setInterval( function(){ alert('你好!setInterval'); } , 200); </script>

瀏覽器的核心是多線程的,它們在核心制控下相互配合以保持同步,一個瀏覽器至少實現3個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。

JavaScript引擎是基於事件驅動單線程執行的,JS引擎一直等待著任務隊列中任務的到來然後加以處理,瀏覽器無論再什麼時候都只有一個JS線程在運行JS程式。
GUI渲染線程負責渲染瀏覽器介面,當介面需要重繪(Repaint)或由於某種操作引發迴流(reflow)時,該線程就會執行。但需要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被儲存在一個隊列中等到JS引擎空閑時立即被執行。
瀏覽器事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器核心的其他線程如滑鼠點擊、AJAX非同步請求等,但由於JS的單線程關係所有這些事件都得排隊等待JS引擎處理。

  由可看出,瀏覽器中的JavaScript引擎是基於事件驅動的,這裡的事件可看作是瀏覽器派給它的各種任務,JavaScript引擎一直等待著任務隊列中任務的到來,由於單線程關係,這些任務得進行排隊,一個接著一個被引擎處理。

t1、t2....tn表示不同的時間點,tn下面對應的小方塊代表該時間點的任務。

t1時刻:

1、GUI渲染線程
2、瀏覽器事件觸發線程:

在t1時間段內,首先是使用者點擊了一個滑鼠鍵,點擊被瀏覽器事件觸發線程捕捉後形成一個滑鼠點擊事件,由圖可知,對於JavaScript引擎線程來說,這事件是由其它線程非同步傳到任務隊列尾的,由於引擎正在處理t1時的任務,這個滑鼠點擊事件正在等待處理。
3、定時觸發線程:
這裡的瀏覽器模型定時計數器並不是由JavaScript引擎計數的,因為JavaScript引擎是單線程的,如果處於阻塞線程狀態就計不了時,它必須依賴外部來計時並觸發定時,所以隊列中的定時事件是非同步事件。
4、在這t1的時間段內,繼滑鼠點擊事件觸發後,先前已設定的setTimeout定時也到達了,此刻對JavaScript引擎來說,定時觸發線程產生了一個非同步定時事件並放到任務隊列中,該事件被排到點擊事件回調之後,等待處理。同理,還是在t1時間段內,接下來某個setInterval定時器也被添加了,由於是間隔定時,在t1段內連續被觸發了兩次,這兩個事件被排到隊尾等待處理。
5、ajax非同步請求:
瀏覽器新開一個http線程請求,當請求的狀態變更時,如果先前已設定回調,這非同步線程就產生狀態變更事件放到JavaScript引擎的處理隊列中等待處理。
二、任務的執行順序不同,顯示結果也不同

1)未使用setTimeout函數

在網上找到的一段代碼執行個體,這裡用來示範一下。

<a href="#" id="doBtn">do something</a><div id="status"></div><script type="text/javascript">  var doBtn = document.getElementById('doBtn')   , status = document.getElementById('status');  function sleep(ms) {  var start = new Date();  while (new Date() - start <= ms) {}  }    doBtn.onclick = function(e) {   status.innerHTML = 'doing...please wait...';    sleep(3000); // 類比一個耗時較長的計算過程,3s   status.innerHTML = 'done';    return false;  };</script>

我在firefox中執行了上面的代碼。計劃是點擊“do something”按鈕,然後顯示“doing...please wait...”,接著執行sleep,最後顯示“done”。

但是結果是點擊後,瀏覽器卡住3秒左右,最後直接顯示done。

分析下看出,在做status.innerHTML設定的時候,是需要執行GUI渲染線程的,但是現在還在執行JavaScript引擎線程,而JavaScript引擎線程與GUI渲染線程是互斥的,所以就最後顯示了done。

 2)使用了setTimeout函數

<a href="#" id="doBtn2">do something timer</a><div id="status2"></div><script type="text/javascript">  var doBtn2 = document.getElementById('doBtn2')   , status2 = document.getElementById('status2');  function sleep2(ms) {  var start = new Date();  while (new Date() - start <= ms) {}  }    doBtn2.onclick = function(e) {   status2.innerHTML = 'doing...please wait...';    setTimeout(function() {   sleep2(3000);    status2.innerHTML = 'done';    }, 100);    return false;  };</script>

在“doing...please wait...”後面加了個setTimeout,延時執行,給了瀏覽器渲染的時間,這個時候會顯示出“doing...please wait...”的字樣,然後執行sleep函數,最後顯示“done”。

後面有網友發現在firefox中不起作用,的確有這個問題,後面我修改了一下代碼,將局部變數的聲明,onclick的綁定放到了window.onload事件中,等頁面結構載入完成後,我再做指令碼操作。

<script type="text/javascript">  function sleep(ms) {  //...  }  window.onload = function() {   var doBtn = document.getElementById('doBtn'),   status = document.getElementById('status');      var doBtn2 = document.getElementById('doBtn2')    , status2 = document.getElementById('status2');       doBtn.onclick = function(e) {    //...   };   doBtn2.onclick = function(e) {    //...   };  };</script>

以上就是本文的全部內容,希望對大家的學習有所協助。

您可能感興趣的文章:
  • 擷取焦點時,利用js定時器設定時間執行動作
  • JS定時器執行個體
  • Javascript/Jquery——簡單定時器的多種實現方法
  • JavaScript定時器詳解及執行個體
  • js定時器怎麼寫?就是在特定時間執行某段程式
  • js 定時器setTimeout無法調用局部變數的解決辦法
  • js定時器的使用(執行個體講解)
  • js定時器(執行一次、重複執行)
  • Nodejs極簡入門教程(二):定時器
  • node.js中的定時器nextTick()和setImmediate()區別分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.