1. 程式人生 > >JavaScript 是單線程的而且是異步的機制

JavaScript 是單線程的而且是異步的機制

孤單 操作dom 自動 頁面 程序 函數 異步調用 tro time

瀏覽器中的js程序是單線程的,那異步調用是怎麽實現的呢?計時器是靠誰實現的呢?單線程難道是一邊執行程序一邊計時嗎?

好了 …………之前就有好多的疑問 ,現在按我的理解和大家說一說

一、JavaScript單線程

  在瀏覽器中,執行JS程序只有一個線程,所以是單線程,所以執行順序就是從上到下依次執行,同一段時間內只能有一段代碼被執行。你可能會問,為什麽不用多線程呢,這樣不是更能充分利用CPU嗎?

  ps:只能說早期的頁面非常簡單,所以我認為設計者沒有考慮多線程的問題 (本人猜想的哈,勿噴!!)。另外,JavaScript主要用來處理用戶與界面的交互,以及操作DOM;可以設想一下,如果一個線程要求刪除DOM,另一個線程要求修改呢,瀏覽器聽誰的??這就增加了程序設計的復雜度,所以簡單點好啊,你說是不是。

  ps:雖然JavaScript是單線程的,可是瀏覽器內部不是單線程的啊,你的一些I/O操作、定時器和事件監聽是由瀏覽器提供的其他線程完成的……

  ##如果想利用多線程處理一些耗時較長的任務,可以使用HTML5提供的Web Worker、

二、任務隊列和事件循環

  理解異步機制的兩個要點:任務隊列和事件循環

  ps:技術分享

三、異步機制

有了上面兩節做鋪墊,理解異步機制就容易多了。拿ajax來說,當頁面的單線程執行xhr.send()之後,對於頁面來說發送任務已經完成了。怎麽發送,那是瀏覽器的事,和單線程無關;什麽時候響應,這事說不準。為了及時地得到響應的內容,在單線程中註冊相應的事件就好xhr.onreadystatechange = fn() {...}

。註冊之後,瀏覽器會在內部的其他線程中自動地幫我們監聽該事件。直到該事件被觸發,瀏覽器會在任務隊列中添加一個任務等待該單線程執行。

四、定時器

setTimeout的作用是在間隔一定的時間後,將回調函數插入任務隊列中,等棧中的同步任務都執行完畢後,再執行。因為棧中的同步任務也會耗時,所以間隔的時間一般會大於等於指定的時間。

setTimeout(fn, 0)的意思是,將回調函數fn立刻插入任務隊列,等待執行,而不是立即執行。看一個例子:

技術分享

五、總結

所謂的單線程並不孤單,它的背後有瀏覽器的其他線程為其服務,其異步也得靠其他線程來監聽事件的響應,並將回調函數推入到任務隊列等待執行。單線程所做的就是執行棧中的同步任務,執行完畢後,再從任務隊列中取出一個事件(沒有事件的話,就等待事件),然後開始執行棧中相關的同步任務,不斷的這樣循環。

JavaScript 是單線程的而且是異步的機制