關于HTML5的Web Worker你了解多少?

2020-09-19 18:39:05 編輯:小船網絡 來源:本站原創

大家都知道,JavaScript是單線程的,也就是說,所有的任務只能在一個線程上完成,一次只能做一件事。前面的任務如果沒有完成,后面就只能等著。所以,HTML5就提出了web Worker標準,表示JavaScript允許有多個線程,但是子線程完全受主線程的控制,并且子線程不能操作DOM,只有主線程可以操作DOM。所以 Web Worker 的最佳使用場景是執行一些開銷較大的數據處理或計算任務。

什么是Web Worker ?

Web Worker 是HTML5標準的一部分,這一規范定義了一套API,它允許一段JavaScript程序運行在主線程之外的另外一個線程中。

值得注意的是, Web Worker 規范中定義了兩類工作線程,分別是專用線程Dedicated Worker和共享線程 Shared Worker。其中,Dedicated Worker只能為一個頁面所使用,而Shared Worker則可以被多個頁面所共享。

如何使用Worker?

使用的時候需要注意的幾個地方

同源限制

分配給 Worker 線程運行的腳本文件,必須與主線程的腳本文件同源。

DOM限制

Worker 線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網頁的 DOM 對象,也無法使用document、window、parent這些對象。但是,Worker 線程可以navigator對象和location對象。

通信

Worker 線程和主線程不在同一個上下文環境,所以它們不能直接通信,必須通過發布訂閱消息完成。

腳本限制

Worker 線程內不能執行alert()方法和confirm()方法,但是可以使用 XMLHttpRequest 對象發送 AJAX 請求。

文件限制

Worker 線程無法讀取本地文件,即不能打開本機的文件系統(file://),它所加載的腳本,必須來自網絡。

如何創建一個Worker?

Worker構造函數,第一個參數是腳本的網址(必須遵守同源政策),該參數是必需的,且只能加載 JS 腳本,否則報錯。

第二個參數是配置對象,該對象可選。它的一個作用就是指定 Worker 的名稱,用來區分多個 Worker 線程。

例如創建一個Worker:

const worker = new Worker('worker.js');

主線程與子線程如何通信?

基本原理就是在當前的主線程中加載一個只讀文件來創建一個新的線程,兩個線程同時存在,且互不阻塞,并且在子線程與主線程之間提供了數據交換的接口postMessage和onmessage。

例如,向Worker子線程發送消息:

// 第一種傳遞方式

worker.postMessage('我是主線程');

// 第二種傳遞方式

worker.postMessage({

  // ArrayBuffer object 

  input: buffer

}, [buffer]);

worker.postMessage()方法的參數,就是主線程傳給子線程 Worker 的數據。它可以是各種數據類型,包括二進制數據。

接收子線程Work發回的消息

worker.onmessage = function (event) {

  console.log('子線程的消息:' + event.data)

}

worker.js子線程向主線程發送消息

self.postMessage('我是子線程')

接收主線程發來的消息

self.onmessage = function (event) {

  console.log('主線程的消息:' + event.data)

}

self代表子線程自身,即子線程的全局對象。

以下是主線程與子線程的常用API

主線程中的,worker表示是 Worker 的實例:

worker.postMessage

主線程往worker線程發消息,消息可以是任意類型數據,包括二進制的數據

worker.terminate

主線程關閉worker線程

worker.onmessage

指定worker線程發消息時的回調

也可以通過 worker.addEventListener('message', cb) 的方式

worker.onerror

指定worker線程發生錯誤時的回調

同樣也可以 worker.addEventListener('error', cb)

Worker線程中全局對象為 self,代表子線程自身,這時this指向self:

self.postMessage

worker線程往主線程發消息,消息可以是任意類型數據,包括二進制數據

self.close

worker線程關閉自己

self.onmessage

指定主線程發worker線程消息時的回調

也可以self.addEventListener('message', cb)

self.onerror

指定worker線程發生錯誤時的回調

也可以 self.addEventListener('error', cb)

self.name

Worker 的名字。該屬性只讀,由構造函數指定。

載入工具函數

importScripts('work1.js', 'work2.js', ...)

importScripts是同步方法,一旦importScripts方法返回就可以開始使用載入的腳本,而不需要回調函數。

共享線程 SharedWorker

共享線程是為了避免線程的重復創建和銷毀過程,降低了系統性能的消耗,共享線程SharedWorker可以同時有多個頁面的線程鏈接。

使用SharedWorker創建共享線程,也需要提供一個javascript腳本文件的URL地址或Blob,該腳本文件中包含了我們在線程中需要執行的代碼,如下:

const sharedworker = new SharedWorker("sharedworker.js");

共享線程也使用了message事件監聽線程消息,但使用SharedWorker對象的port屬性與線程通信如下。

sharedworker.port.onmessage = function (event) {

  console.log(event.data)

}

也可以使用SharedWorker對象的port屬性向共享線程發送消息

sharedworker.port.postMessage('Hello World');

本站文章均為小船網站建設摘自權威資料,書籍,或網絡原創文章,如有版權糾紛或者違規問題,請即刻聯系我們刪除,我們歡迎您分享,引用和轉載,我們謝絕直接復制和抄襲!感謝...
我們猜你喜歡
伊人久久大线蕉av色首页