网络工作者

了解使用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初学者手册


更多浏览器教程: