javascript既然是單執行緒語言 , 為什麼會分主執行緒和訊息執行緒(event loop) ?
xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){} //傳入我們的回撥 xhr.open(...) xhr.send(...)
瀏覽器雖然會在一個單獨的執行緒去進行網路請求,但是我們是通過傳遞一個回撥的方式去處理資料,瀏覽器在網路請求成功後,然後會切換回js執行緒來執行我們的回撥,也就是說我們所有的js程式碼都是在js執行緒中執行的。所以javascript確實是在一個單執行緒中,而web worker不同,我們的js程式碼可以執行在js主執行緒之外,這也是為什麼不能在web worker裡面直接共享js主執行緒中定義的變數,不能操作ui (dom樹)的原因,因為根本不在一個執行緒!其實說的這裡,可以繼續往深的說,比如為什麼不能在工作執行緒中操作ui? 太深了就跑題了,如果有人感興趣,可以私我。我們稍微再說一些,比如igetit同學文章中提到了作業系統的程序和執行緒,既然你們都點過贊,那就證明已經看到了,可能有人會說,程序的地址空間是隔離的,但同一個程序的執行緒之見是可以共享資料的,為什麼web worker和js 雖然不在同一執行緒,但是如果在同一個程序中,也是應該能共享變數的,為甚麼web worker和js 主執行緒之見藥通過訊息對列這種複雜的方式來傳遞資料?為什麼不允許在web worker中操作UI? 如果有這些問題問的很好,但是我並不打算在此問題中回答,畢竟和題主問題不大,還是那句話,如果有興趣可以私我。
下面再看一個igetit同學對瀏覽器為什麼設計成單執行緒,和JavaScript可否設計成多執行緒?的回答:說最初是因為硬體配置低,所以沒有考慮多執行緒,後來有機會但是,好在js支援非同步,也就沒有實現。
我敢保證igetit同學沒有做過系統原生的ui開發!無論是windows c開發,活著java 介面開發,一條黃金原則就是不要在其它執行緒中操作ui,android中如果發現在非ui執行緒中操作ui會直接丟擲異常!好,繼續說,其實阮一峰這篇文章中對
現在我們回到題主的問題,zeromike 同學的回答其實已經說明了問題,但大家贊卻點錯了地方。 正如ajax回撥一樣,js vm會將我們所有的回撥都會放在一個隊列當中,比如我們監聽的某個單擊事件的回撥,當用戶單擊了我們監聽的元素,瀏覽器捕獲到事件,然後就去執行我們的回撥,而執行回撥的環境都在同一個javasricpt執行緒中,其實也就是說event loop是在瀏覽器中的,而javascript是執行在同一個執行緒當中的!這也是js的特點-非同步,node中也是延續了這個特點,當然,為了利用多核cpu,node 提供了child_process 。但這不是嚴格意義上的多執行緒,相當於起了多個node例項,也就有多個js執行緒。