JavaScript語言採用的是單一線程模型,也就是說,所有任務排成一個佇列,一次只能做一件事。無法充分發揮JavaScript的潛能。就是為JavaScript創造多執行緒環境,讓主執行緒將一些任務指派給子執行緒 在主執行緒運行的同時,子執行緒在後台運行,兩者互不干擾。主執行緒。 ##同域限制:子執行緒載入的腳本文件,必須與主執行緒的腳本文件在同一個網域。即document、window、parent這些對象,子執行緒都無法得到。變數和函數,也不能執行alert和confirm方法,不過可以執行setInterval和setTimeout,以及使用XMLHttpRequest物件發出AJAX請求。即子執行緒無法開啟本機的檔案系統(file://),它所載入的腳本,必須來自網路。支援的瀏覽器包括IE 10+、Firefox 3.6+、Safari 4.0+、Chrome 和Opera 11,但手機瀏覽器還不支援。在主執行緒內部,採用new指令呼叫Worker方法,可以新建一個子執行緒。上面程式碼中是work.js。 子執行緒新建之後,並沒有啟動,必要等待主執行緒呼叫postMessage方法,也就是發出訊號之後才會啟動。
if (window.Worker) { // 支持} else { // 不支持}
postMessage方法的參數,就是主執行緒傳給子執行緒的訊號。它即可以是一個
字串,也可以是一個物件。
var worker = new Worker('work.js');
監聽
,監聽message事件。
worker.postMessage('hello world');
的值也可以)。回呼
函數的參數根據主執行緒發出的不同的訊號值,子執行緒可以呼叫不同的方法。
worker.postMessage({method: 'each', args: ['work']});
主執行緒也必須指定message事件的回呼函數,監聽子執行緒發出的訊號。
//File: work.jsself.addEventListener('message', function(e) { self.postMessage('You said: ' + e.data); }, false);
主執行緒可以監聽子執行緒是否發生錯誤。如果發生錯誤,會觸發主執行緒的error事件。
'message', method = args = reply =);
6、關閉子執行緒
使用完畢後,為了節省系統資源,我們必須在主執行緒呼叫terminate方法,手動關閉子執行緒。
// File: main.jsworker.addEventListener('message', function(e) { console.log(e.data); }, false);
也可以子執行緒內部關閉自身。 worker.onerror(function(e) {
console.log(e);
});// orworker.addEventListener('error', function(e) {
console.log(e);
}, false);
主執行緒也子執行緒這間也可以交換二進位數據,例如File、Blob、ArrayBuffer等對象,也可以在執行緒之間傳送。
但是,用拷贝方式发送二进制数据,会造成性能问题。比如,主线程向子线程发送一个500MB文件,默认情况下浏览器会生成一个原文件的拷贝。为了解决这个问题,JavaScript允许主线程把二进制数据直接转移给子线程,但是一旦转移,主线程就无法再使用这些二进制数据了,这是为了防止出现多个线程同时修改数据的麻烦局面。这种转移数据的方法,叫做Transferable Objects。
如果要使用该方法,postMessage方法的最后一个参数必须是一个数组,用来指定前面发送的哪些值可以被转移给子线程。
worker.postMessage(arrayBuffer, [arrayBuffer]);
通常情况下,子线程载入的是一个单独的JavaScript文件,但是也可以载入与主线程在同一个网页的代码。假设网页代码如下:
<!DOCTYPE html> <body> <script id="worker" type="app/worker"> addEventListener('message', function() { postMessage('Im reading Tech.pro'); }, false); </script> </body></html>
我们可以读取页面的script,用worker来处理。
var blob = new Blob([document.querySelector('#workere').textContent]);
这里需要把代码当作二进制数据读取,所以使用Blob接口。然后,这个二进制对象转为URL,再通过这个URL创建worker。
var url = window.URL.createObjectURL(blob);var worker = new Worker(url);
部署事件监听代码。
worker.addEventListener('message', function(e) { console.log(e.data); }, false);
最后启动worker。
worker.postMessage('');
整个页面的代码如下:
<script> (function() { var blob = new Blob([document.querySelector('#worker').textContent]); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); worker.addEventListener('message', function(e) { console.log(e.data); }, false); worker.postMessage(&#39;&#39;); })(); </script>