網絡工作者

了解使用Web Workers在後台運行JavaScript代碼的方法

介紹

JavaScript是單線程的。任何事物都不能同時並行運行。

這很棒,因為我們不必擔心並發編程會發生的所有問題。

受此限制,JavaScript代碼從一開始就被迫提高效率,否則用戶將有糟糕的體驗。昂貴的操作應該是異步的,以避免阻塞線程。

隨著JavaScript應用程序需求的增長,在某些情況下這已成為問題。

Web Workers引入了在瀏覽器內部並行執行的可能性。

它們有很多限制:

  • 無法訪問DOM:Window對象和Document對象
  • 他們可以使用消息傳遞與主要的JavaScript程序進行通信
  • 它們需要從相同的來源(域,端口和協議)加載
  • 如果您使用文件協議(file://

Web Worker的全局範圍是主線程,而不是主線程中的Window。WorkerGlobalScope目的。

瀏覽器對Web Worker的支持

不錯!

Browser support for web workers

您可以使用以下方法檢查Web Workers支持

if (typeof Worker !== 'undefined') {
}

創建一個Web Worker

您可以通過初始化一個Worker對象來創建Web Worker,並從相同的來源加載JavaScript文件:

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

與Web Worker的通信

與Web Worker進行通信的主要方法有兩種:

在Web Worker對像中使用postMessage

您可以使用以下方式發送消息postMessageWorker目的。

重要提示:郵件已傳輸而不是共享。

main.js

const worker = new Worker('worker.js')
worker.postMessage('hello')

worker.js

onmessage = event => {
  console.log(event.data)
}

onerror = event => { console.error(event.message) }

發回訊息

工作人員可以將消息發送回創建它的函數。使用其全球postMessage()功能:

worker.js

onmessage = event => {
  console.log(event.data)
  postMessage('hey')
}

onerror = event => { console.error(event.message) }

main.js

const worker = new Worker('worker.js')
worker.postMessage('hello')

worker.onmessage = event => { console.log(event.data) }

多個事件監聽器

如果您想為message事件,而不是使用onmessage創建一個事件監聽器(適用於error事件):

worker.js

addEventListener('message', event => {
  console.log(event.data)
  postMessage('hey')
}, false)

addEventListener(‘message’, event => { console.log(I'm curious and I'm listening too) }, false)

addEventListener(‘error’, event => { console.log(event.message) }, false)

main.js

const worker = new Worker('worker.js')
worker.postMessage('hello')

worker.addEventListener(‘message’, event => { console.log(event.data) }, false)

使用頻道消息傳遞API

除了使用Web Workers提供的內置postMessage API外,我們可以選擇使用更通用的頻道訊息API與他們交流。

main.js

const worker = new Worker('worker.js')
const messageChannel = new MessageChannel()
messageChannel.port1.addEventListener('message', event => {
  console.log(event.data)
})
worker.postMessage(data, [messageChannel.port2])

worker.js

addEventListener('message', event => {
  console.log(event.data)
})

Web Worker可以通過將消息發佈到來發送回消息messageChannel.port2, 像這樣:

addEventListener('message', event => {
  event.ports[0].postMessage(data)
})

網絡工作者生命週期

啟動了Web Worker,如果他們不停留在偵聽模式下,則通過worker.onmessage或通過添加事件偵聽器,將在代碼運行完成後立即將其關閉。

Web Worker可以使用其停止terminate()方法從主線程開始,並在工作程序本身內部使用全局方法close()

main.js

const worker = new Worker('worker.js')
worker.postMessage('hello')
worker.terminate()

worker.js

worker.onmessage = event => {
  console.log(event.data)
  close()
}

worker.onerror = event => { console.error(event.message) }

在Web Worker中加載庫

網絡工作者可以使用importScripts()在其全局範圍內定義的全局函數:

importScripts('../utils/file.js', './something.js')

Web Workers中可用的API

如前所述,Web Worker無法訪問DOM,因此您無法與windowdocument對象。還parent不可用。

但是,您可以使用許多其他API,包括:

免費下載我的JavaScript初學者手冊


更多瀏覽器教程: