JavaScript
線程機制與事件機制process
)windows
任務管理器查看進程。thread
)CPU
的最小調度單元。
thread pool
):保存多個線程對象的容器,實現線程對象的反覆利用。(1)何爲多進程與多線程?javascript
(2)比較單線程與多線程?css
多線程html
CPU
的利用率。缺點:java
單線程web
(3)JS
是單線程仍是多線程?ajax
JS
是單線程運行的。H5
中的 Web Workers
能夠多線程運行。(4)瀏覽器運行是單線程仍是多線程?編程
(5)瀏覽器運行是單進程仍是多進程?windows
有的是單進程:跨域
Firefox
IE
有的是多進程:瀏覽器
Chrome
Firefox
IE
如何查看瀏覽器是不是多進程運行的呢?
(1)瀏覽器內核是支撐瀏覽器運行的最核心的程序。
(2)不一樣的瀏覽器內核不同:
Chrome
,Safari
:webkit
Firefox
:Gecko
IE
:Trident
360
,搜狗等國內瀏覽器:Trident+webkit
(3)內核由不少模塊組成:
主線程
js
引擎模塊:負責js
程序的編譯與運行。html
,css
文檔解析模塊:負責頁面文本的解析。DOM/CSS
模塊:負責DOM/CSS
在內存中的相關處理。分線程
DOM
事件響應模塊:負責事件的管理。ajax
)。(1)定時器真是定時執行的嗎?
<button id="btn">啓動定時器</button> document.getElementById('btn').onclick = function () { var start = Date.now() console.log('啓動定時器前...') setTimeout(function () { console.log('定時器執行了', Date.now()-start) }, 200) console.log('啓動定時器後...') }
給上面回調函數加一個長時間的任務:
document.getElementById('btn').onclick = function () { var start = Date.now() console.log('啓動定時器前...') setTimeout(function () { console.log('定時器執行了', Date.now()-start) }, 200) console.log('啓動定時器後...') // 作一個長時間的工做 for (var i = 0; i < 1000000000; i++) {} }
結果:
同步任務執行完以後纔會執行異步任務。
(2)定時器回調函數是在分線程執行的嗎?
js
是單線程的。(3)定時器是如何實現的?
JS
是單線程執行的(1)如何證實js
執行是單線程的?
setTimeout()
的回調函數是在主線程執行的。(2)爲何js
要用單線程模式, 而不用多線程模式?
JavaScript
的單線程,與它的用途有關。JavaScript
的主要用途是與用戶互動,以及操做DOM
。(3)代碼的分類:
(4)js
引擎執行代碼的基本流程
先執行初始化代碼: 包含一些特別的代碼 ,回調函數(異步執行)
ajax
請求
(1)執行棧
execution stack
(2)瀏覽器內核
browser core
js
引擎模塊(在主線程處理)(3)任務隊列(callback queue
)
task queue
(4)消息隊列(callback queue
)
message queue
(5)事件隊列(callback queue
)
event queue
(6)事件輪詢
event loop
(7)事件驅動模型
event-driven interaction model
(8)請求響應模型
request-response model
(1)全部代碼分類:
dom
事件監聽, 設置定時器, 發送ajax
請求的代碼。(2)js
引擎執行代碼的基本流程:
(3)模型的2個重要組成部分:
(4)模型的運轉流程:
(a)執行初始化代碼, 將事件回調函數交給對應模塊管理。
(b)當事件發生時, 管理模塊會將回調函數及其數據添加到回調列隊中。
(c)只有當初始化代碼執行完後(可能要必定時間), 纔會遍歷讀取回調隊列中的回調函數執行。
H5 Web Workers
(多線程)Web Workers
是 HTML5
提供的一個Javascript
多線程解決方案。Web Worker
運行而不凍結用戶界面。DOM
。因此,這個新標準並無改變JavaScript
單線程的本質相關API
Worker
: 構造函數, 加載分線程執行的js
文件。Worker.prototype.onmessage
: 用於接收另外一個線程的回調函數。Worker.prototype.postMessage
: 向另外一個線程發送消息。JS
文件var onmessage = function (event){ //不能用函數聲明 console.log('onMessage()22'); var upper = event.data.toUpperCase();//經過event.data得到發送來的數據 postMessage( upper );//將獲取到的數據發送回主線程 }
JS
中發消息並設置回調//建立一個Worker對象並向它傳遞將在新線程中執行的腳本的URL var worker = new Worker("worker.js"); //接收worker傳過來的數據函數 worker.onmessage = function (event) { console.log(event.data); }; //向worker發送數據 worker.postMessage("hello world");
編程實現斐波那契數列(Fibonacci sequence)的計算 F(0)=0,F(1)=1,..... F(n)=F(n-1)+F(n-2)
var fibonacci =function(n) { return n <2 ? n : fibonacci(n -1) + fibonacci(n -2); }; console.log(fibonacci(48));
使用Web Workers
在分線程:
var worker = new Worker('worker2.js'); worker.addEventListener('message', function (event) { var timer2 = new Date().getTime(); console.log('結果:' + event.data, '時間:' + timer2, '用時:' + ( timer2 - timer )); }, false); var timer = new Date().getTime(); console.log('開始計算: ', '時間:' + timer); setTimeout(function () { console.log('定時器函數在計算數列時執行了', '時間:' + new Date().getTime()); }, 1000); worker.postMessage(40); console.log('我在計算數列的時候執行了', '時間:' + new Date().getTime());
var fibonacci =function(n) { return n <2 ? n : fibonacci(n -1) + fibonacci(n -2); }; var onmessage = function(event) { var n = parseInt(event.data, 10); postMessage(fibonacci(n)); };
JS
。worker
內代碼不能訪問DOM
(更新UI
)。