欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文讀懂JavaScript多線程Web?Worker

 更新時(shí)間:2025年03月02日 21:39:10   投稿:wdc  
HTML5就提出了web?Worker標(biāo)準(zhǔn),表示JavaScript允許有多個(gè)線程,但是子線程完全受主線程的控制,并且子線程不能操作DOM,只有主線程可以操作DOM

前言

大家都知道,JavaScript是單線程的,也就是說,所有的任務(wù)只能在一個(gè)線程上完成,一次只能做一件事。前面的任務(wù)如果沒有完成,后面就只能等著。所以,HTML5就提出了web Worker標(biāo)準(zhǔn),表示JavaScript允許有多個(gè)線程,但是子線程完全受主線程的控制,并且子線程不能操作DOM,只有主線程可以操作DOM。所以 Web Worker 的最佳使用場景是執(zhí)行一些開銷較大的數(shù)據(jù)處理或計(jì)算任務(wù),接下來我們就來具體的了解一下這個(gè)東西吧~

正文

什么是Web Worker ?

Web Worker 是HTML5標(biāo)準(zhǔn)的一部分,這一規(guī)范定義了一套API,它允許一段JavaScript程序運(yùn)行在主線程之外的另外一個(gè)線程中。

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

如何使用Worker?

使用的時(shí)候需要注意的幾個(gè)地方

  • 同源限制
    分配給 Worker 線程運(yùn)行的腳本文件,必須與主線程的腳本文件同源。
  • DOM限制
    Worker 線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網(wǎng)頁的 DOM 對象,也無法使用document、window、parent這些對象。但是,Worker 線程可以navigator對象和location對象。
  • 通信
    Worker 線程和主線程不在同一個(gè)上下文環(huán)境,所以它們不能直接通信,必須通過發(fā)布訂閱消息完成。
  • 腳本限制
    Worker 線程內(nèi)不能執(zhí)行alert()方法和confirm()方法,但是可以使用 XMLHttpRequest 對象發(fā)送 AJAX 請求。
  • 文件限制
    Worker 線程無法讀取本地文件,即不能打開本機(jī)的文件系統(tǒng)(file://),它所加載的腳本,必須來自網(wǎng)絡(luò)。

如何創(chuàng)建一個(gè)Worker?

Worker構(gòu)造函數(shù),第一個(gè)參數(shù)是腳本的網(wǎng)址(必須遵守同源政策),該參數(shù)是必需的,且只能加載 JS 腳本,否則報(bào)錯。
第二個(gè)參數(shù)是配置對象,該對象可選。它的一個(gè)作用就是指定 Worker 的名稱,用來區(qū)分多個(gè) Worker 線程。

例如創(chuàng)建一個(gè)Worker

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

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

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

例如,向Worker子線程發(fā)送消息

// 第一種傳遞方式
worker.postMessage('我是主線程');

// 第二種傳遞方式
worker.postMessage({
  // ArrayBuffer object 
  input: buffer
}, [buffer]);

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

接收子線程Work發(fā)回的消息

worker.onmessage = function (event) {
  console.log('子線程的消息:' + event.data)
}

worker.js子線程向主線程發(fā)送消息

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

接收主線程發(fā)來的消息

self.onmessage = function (event) {
  console.log('主線程的消息:' + event.data)
}

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

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

主線程中的,worker表示是 Worker 的實(shí)例:

  • worker.postMessage
    主線程往worker線程發(fā)消息,消息可以是任意類型數(shù)據(jù),包括二進(jìn)制的數(shù)據(jù)
  • worker.terminate
    主線程關(guān)閉worker線程
  • worker.onmessage
    指定worker線程發(fā)消息時(shí)的回調(diào)
    也可以通過 worker.addEventListener('message', cb) 的方式
  • worker.onerror
    指定worker線程發(fā)生錯誤時(shí)的回調(diào)
    同樣也可以 worker.addEventListener('error', cb)

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

  • self.postMessage
    worker線程往主線程發(fā)消息,消息可以是任意類型數(shù)據(jù),包括二進(jìn)制數(shù)據(jù)
  • self.close
    worker線程關(guān)閉自己
  • self.onmessage
    指定主線程發(fā)worker線程消息時(shí)的回調(diào)
    也可以self.addEventListener('message', cb)
  • self.onerror
    指定worker線程發(fā)生錯誤時(shí)的回調(diào)
    也可以 self.addEventListener('error', cb)
  • self.name
    Worker 的名字。該屬性只讀,由構(gòu)造函數(shù)指定。

載入工具函數(shù)

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

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

共享線程 SharedWorker

共享線程是為了避免線程的重復(fù)創(chuàng)建和銷毀過程,降低了系統(tǒng)性能的消耗,共享線程SharedWorker可以同時(shí)有多個(gè)頁面的線程鏈接。
使用SharedWorker創(chuàng)建共享線程,也需要提供一個(gè)javascript腳本文件的URL地址或Blob,該腳本文件中包含了我們在線程中需要執(zhí)行的代碼,如下:

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

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

sharedworker.port.onmessage = function (event) {
  console.log(event.data)
}

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

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

到此這篇關(guān)于一文讀懂JavaScript多線程Web Worker的文章就介紹到這了,更多相關(guān)JavaScript多線程Web Worker內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論