Web Worker API

簡介

  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

特徵ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
基本支撐43.5 (1.9.1)10.010.64
同享worker429未完成10.66.1

Mobile

特徵AndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
基本支撐4.443.51.0.110.011.55.1
同享worker未完成481.0.1未完成未完成未完成
    原文作者:shjeff
    原文地址: https://segmentfault.com/a/1190000015438817
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞