簡介
Web Worker可以理解為js在背景線程中運轉的要領,它可以實行js代碼而不壅塞用戶UI界面。一個Web Worker可以將音訊發送到建立它的JavaScript代碼(只需運轉在同源的父頁面中,workers可以順次天生新的workers), 反之也可以從主線程吸收音訊
注重:worker運轉在另一個全局高低文中,差別於當前的window。因而,運用window快捷體式格局獵取當前全局的局限,在一個Worker內將返回毛病(直接接見你須要接見的屬性即可!如:console而不是window.console)。
worker中可用函數和接口
在WebWorker中有些要領和屬性是不能被接見的,比方BOM的一些API和DOM相干的一些API,localStorage,SessionStorage等,然則大部份的window對象是可以被接見的比方:Websocket,XMLHttpRequest(一樣不能跨域☹)Console Api,Array,Date,Math,String等等,就是說涉及到頁面操作和頁面中的對象一切不能被接見,它的運用場景是替換主線程實行須要斲喪頁面機能的代碼。這裡有一份關於WebWorker許可接見的要領及屬性清單
重要wroker範例
經常使用worker為專用worker(僅在單一劇本中被運用)和同享worker(以同時被多個劇本運用);DedicatedWorkerGlobalScope和SharedWorkerGlobalScope對象離別代表它們的高低文
運用
為了更好的毛病處置懲罰掌握及向下兼容須要做些兼容檢測
if (window.Worker) {
some codes ...
}
天生Worker
挪用Worker()組織函數建立一個Worker對象,該對象吸收指定的URL劇本(劇本必需恪守同源戰略否則將拋出毛病)
var myWorker = new Worker('worker.js');
數據通報
主線程和worker線程都運用postMessage()要領發送各自的音訊,運用onmessage事宜處置懲罰函數來相應音訊(音訊被包含在Message事宜的data屬性中),這個歷程當中數據並非被同享而是被複制。在主線程中運用時,onmessage和postMessage() 必需掛在worker對象上,而在worker中運用時不必如許做。原因是,在worker內部,worker是有用的全局作用域。
/*主線程*/
//發送數據至worker
myWorker.postMessage('can you hear me?');
//從worker線程監聽吸收數據
myWorker.onmessage = function(e) {
console.log(e.data);//'I can hear you!'
}
/*worker線程*/
//從主線程監聽吸收數據
onmessage = function(e) {
console.log(e.data);//'can you hear me?'
//發送數據至worker
e.data && postMessage('I can hear you!');
}
停止worker
假如你須要從主線程中馬上停止一個運轉中的worker,可以挪用worker的terminate要領:
myWorker.terminate();//worker 線程會被馬上殺死
在worker線程中,workers 也可以挪用本身的close要領舉行封閉:
close();
毛病處置懲罰
當worker湧現運轉中毛病時,它的onerror事宜處置懲罰函數會被挪用。它會收到一個擴大了 ErrorEvent 接口的名為 error的事宜。該事宜不會冒泡而且可以被作廢;為防備觸發默許行動,worker可以挪用毛病事宜的preventDefault()要領。
毛病事宜有以下三个中心的字段:
message
可讀性優越的毛病音訊。
filename
發作毛病的劇本文件名。
lineno
發作毛病時地點劇本文件的行號。
天生子worker
假如須要worker可以天生更多的worker。即subworker,但必需託管在同源的父頁面內。注重:subworker剖析 URI時會相對於父worker的地點而不是本身頁面的地點。這使得worker更輕易紀錄它們之間的依靠關聯。
引入劇本與庫
Worker 線程可以接見一個全局函數importScripts()來引入劇本,該函數接收0個或許多個URI作為參數來引入資本;以下例子都是正當的:
importScripts();//什麼都不引入
importScripts('foo.js');//只引入"foo.js
importScripts('foo.js', 'bar.js');//引入兩個劇本
注重: 劇本的下載遞次不牢固,但實行時會根據傳入 importScripts() 中的文件名遞次舉行。這個歷程是同步完成的;直到一切劇本都下載並運轉終了, importScripts() 才會返回。
關於同享worker
一個同享worker可以被多個劇本運用——縱然這些劇本正在被差別的window、iframe或許worker接見。
天生同享worker
var myWorker = new SharedWorker('worker.js');//和專用worker差別組織器為SharedWorker
數據通報
和專用worker差別的是與一個同享worker通訊必需經由過程端口對象即一個確實的翻開的端供詞劇本與worker通訊(在專用worker中這一部份是隱式舉行的)。
在通報音訊之前,端口銜接必需被顯式的翻開,翻開體式格局是運用onmessage事宜處置懲罰函數或許start()要領:
//體式格局1
myWorker.port.onmessage = function(e) {
...
}
//體式格局2(只在一種情況下須要,那就是音訊事宜被addEventListener()要領運用。)
myWorker.port.start();
myWorker.port.addEventListener('message',function(e){
...
})
然後就可以像之前那樣發送和吸收音訊了,然則postMessage()要領必需被端口對象挪用:
/*主線程*/
myWorker.port.postMessage('I posted some message!');//發送
myWorker.port.onmessage = function(e) {//監聽吸收
...
}
/*worker線程*/
onconnect = function(e) {
var port = e.ports[0];
port.onmessage = function(e) {
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
port.postMessage(workerResult);
}
}
在worker線程中須要注重的是:當一個端口銜接被建立時(比方:在父級線程中,設置onmessage事宜處置懲罰函數,或許顯式挪用start()要領時),運用onconnect事宜處置懲罰函數來實行代碼。諸如postMessage()和onmessage也必需在端口銜接上接見。
瀏覽器兼容
Desktop
特徵 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
基本支撐 | 4 | 3.5 (1.9.1) | 10.0 | 10.6 | 4 |
同享worker | 4 | 29 | 未完成 | 10.6 | 6.1 |
Mobile
特徵 | Android | Chrome for Android | Firefox Mobile (Gecko) | Firefox OS (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|---|
基本支撐 | 4.4 | 4 | 3.5 | 1.0.1 | 10.0 | 11.5 | 5.1 |
同享worker | 未完成 | 4 | 8 | 1.0.1 | 未完成 | 未完成 | 未完成 |