了解使用Web Workers在后台运行JavaScript代码的方法
介绍
JavaScript是单线程的。任何事物都不能同时并行运行。
这很棒,因为我们不必担心并发编程会发生的所有问题。
受此限制,JavaScript代码从一开始就被迫提高效率,否则用户将有糟糕的体验。昂贵的操作应该是异步的,以避免阻塞线程。
随着JavaScript应用程序需求的增长,在某些情况下这已成为问题。
Web Workers引入了在浏览器内部并行执行的可能性。
它们有很多限制:
- 无法访问DOM:Window对象和Document对象
- 他们可以使用消息传递与主要的JavaScript程序进行通信
- 它们需要从相同的来源(域,端口和协议)加载
- 如果您使用文件协议(
file://
)
Web Worker的全局范围是主线程,而不是主线程中的Window。WorkerGlobalScope
目的。
浏览器对Web Worker的支持
不错!
您可以使用以下方法检查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 API
- 这频道讯息API
在Web Worker对象中使用postMessage
您可以使用以下方式发送消息postMessage
在Worker
目的。
重要提示:邮件已传输而不是共享。
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,因此您无法与window
和document
对象。还parent
不可用。
但是,您可以使用许多其他API,包括:
- 这XHR API
- 这提取API
- BroadcastChannel API
- 这FileReader API
- 索引数据库
- 这通知API
- 承诺
- 服务人员
- 这频道讯息API
- 这缓存API
- 这控制台API(
console.log()
和朋友) - 这JavaScript计时器(
setTimeout
,setInterval
…) - CustomEvents API:
addEventListener()
和removeEventListener()
- 当前网址,您可以通过以下网址访问
location
读取模式下的属性 - Web套接字
- WebGL
- SVG动画
免费下载我的JavaScript初学者手册
更多浏览器教程:
- HTML5提供了一些有用的技巧
- 我如何使基于CMS的网站脱机工作
- 渐进式Web应用程序完整指南
- 提取API
- 推送API指南
- 频道消息传递API
- 服务人员教程
- 缓存API指南
- 通知API指南
- 深入IndexedDB
- Selectors API:querySelector和querySelectorAll
- 通过延迟和异步有效地加载JavaScript
- 文档对象模型(DOM)
- Web存储API:本地存储和会话存储
- 了解HTTP Cookies的工作原理
- 历史API
- WebP图像格式
- XMLHttpRequest(XHR)
- 深入的SVG教程
- 什么是数据网址
- 学习网络平台的路线图
- CORS,跨域资源共享
- 网络工作者
- requestAnimationFrame()指南
- 什么是Doctype
- 使用DevTools控制台和控制台API
- 语音合成API
- 如何在纯JavaScript中等待DOM ready事件
- 如何将类添加到DOM元素
- 如何遍历来自querySelectorAll的DOM元素
- 如何从DOM元素中删除类
- 如何检查DOM元素是否具有类
- 如何更改DOM节点值
- 如何将click事件添加到从querySelectorAll返回的DOM元素列表中
- WebRTC,实时Web API
- 如何在JavaScript中获取元素的滚动位置
- 如何替换DOM元素
- 如何只接受输入文件字段中的图像
- 为什么要使用浏览器的预览版?
- Blob对象
- 文件对象
- FileReader对象
- FileList对象
- ArrayBuffer
- ArrayBufferView
- URL对象
- 类型数组
- DataView对象
- BroadcastChannel API
- Streams API
- FormData对象
- 导航器对象
- 如何使用地理位置API
- 如何使用getUserMedia()
- 如何使用拖放API
- 如何在网页上滚动
- 在JavaScript中处理表单
- 键盘事件
- 鼠标事件
- 触摸事件
- 如何从DOM元素中删除所有子级
- 如何使用原始Javascript创建HTML属性
- 如何检查是否使用JavaScript选中了复选框?
- 如何使用JavaScript复制到剪贴板
- 如何使用JavaScript禁用按钮
- 如何在浏览器中使页面可编辑
- 如何使用URLSearchParams在JavaScript中获取查询字符串值
- 如何一次删除页面上的所有CSS
- 如何使用insertAdjacentHTML
- Safari,退出前警告
- 如何使用JavaScript将图像添加到DOM
- 如何重设表格
- 如何使用Google字体