javascript本身就是一個單線程的語言,一開始它的出現是為了簡單的網頁設計,設計者並沒有考慮到多線程的問題,要知道,線程的開銷是非常昂貴的。但是隨着web開發的潮流化,javascript不是僅僅一門網頁腳本語言那么簡單了,它可以涉及到socket(websocket),canvas等復雜的操作,這時候單線程的計算遠遠不夠,在此時html5引入了webworker(多線程)對象,用於實現js的多線程操作,雖然本身js還是門單線程的語言,實現多線程是基於Event loop的實現,這里介紹更加詳細http://blog.jobbole.com/30445/。
1.webworker分為Worker(專用線程) 和 SharedWorker(共享線程)兩種,都必須遵守同源策略
同源策略:
為了能和服務器交互,worker必須遵守同源策略(same-origin policy)(譯注:可參考國人文章同源策略)。比如,位於http://www.example.com/內的腳本文件不能訪問https://www.example.com的腳本。盡管域名相同,但同源策略要求端口也必須一致。通常,這不會成為一個很大的問題。但是你很有可能會同一個域名編寫worker和client,所以知道這點對你總是有所幫助。
(1)Worker(專用線程)一般用於交換信息,而不是共享信息,而SharedWorker則用於共享信息
(2)因為worker一般都是在后台運行的,所以不建議在worker中訪問DOM,並進行一系列的DOM操作
2.在這里為了粗略介紹,我們只講Worker(專用線程),有興趣了解ShareWorker的可以在這里參考
我們將會做一個加載圖片的demo,其中有三個文件:test.html,Fthread.js(父線程),Sthread.js(子線程),test.png位於web服務器網站的根目錄下
test.html
<!DOCTYPE html> <html> <body> </body> <script src="Fthread.js"></script> </html>
Fthread.js
var worker = new Worker("Sthread.js"); 創建一個子進程 worker.addEventListener("message", function(e) { e = window.event || e; //加入一些js hack var imgSrc = e.data; //收到子進程傳遞過來的數據 //創建一個圖片便簽並在頁面顯示圖片 var img = document.createElement("img"); img.src = imgSrc; document.body.appendChild(img); /*由父進程關閉終止子進程*/ //this.terminate(); }); //很重要,不可少,這個將會觸發向子進程的請求 worker.postMessage("begin");
Sthread.js
//當收到父進程傳遞過來的消息時,子進程響應,發回圖片url onmessage = function(e){ e = window.event || e; if (e.data === "begin") { postMessage("test.png"); } } this.close();//關閉子進程 }
需要注意的是,chrome不支持本地測試,最好使用其他瀏覽器測試。
3.除次之外,我們還可以進行線程嵌套,即子線程再創建一個子進程,只需要在Sthread.js作些修改
//當收到父進程傳遞過來的消息時,子進程響應,發回圖片url onmessage = function(e){ e = window.event || e; if (e.data === "begin") { var worker = new Worker("SSThread.js");//再創建子進程 worker.onmessage = function(e1) { e1 = window.event || e1; postMessage(e1.data); //返回圖片url到父進程 } worker.postMessage("get url"); } this.close();//關閉子進程 }
SSthread.js
//當收到父進程傳遞過來的消息時,子進程響應,發回圖片url onmessage = function(e){ e = window.event || e; if (e.data === "get url") { postMessage("test.png"); //返回圖片url到父進程 } } this.close();//關閉子進程 }
關於線程嵌套的內容暫時講到這里了,小弟也是初學,還有很多需要嘗試和學習。若有什么出錯的地方,歡迎指出