Web Worker 入门指南

news/2025/11/11 18:08:19/文章来源:https://www.cnblogs.com/hanqin/p/19206838

在浏览器环境中,JavaScript 是单线程运行的,这意味着当执行一些耗时的操作时(例如大量计算、数据处理等),会阻塞主线程,导致用户界面卡顿,影响用户体验。为了解决这个问题,Web Worker 提供了一种在后台线程中运行脚本的方法,从而避免阻塞主线程。

1. 什么是 Web Worker

Worker 是一个使用构造函数创建的对象(例如 Worker()),它运行一个具名 JavaScript 文件,该文件包含将在 Worker 线程中运行的代码。Worker 运行在另一个全局上下文中,不同于当前的 window。在 Worker 内通过 self 获取全局作用域,而不是 window。

2. Web Worker 的基本用法

2.1 创建 Worker 线程

要创建一个 Worker,需要使用 Worker 构造函数,并传入一个 JavaScript 文件的路径作为参数。例如,假设我们有一个名为 worker.js 的文件:

// worker.js
self.onmessage = (event) => {console.log('worker event: ', event)
};
// 主线程
const worker = new Worker('worker.js');

注:这里的 worker.js 必须与主线程在同一域名下。如果使用构建工具,还需要注意打包后的路径问题

2.2 主线程发送消息给 Worker 线程

要向 Worker 线程发送消息,需要调用 worker.postMessage() 方法,并传入一个要发送的数据作为参数。例如:

// 主线程
const worker = new Worker('worker.js');
worker.postMessage({ num: 10 });

运行后我们可以看到 Worker 线程中接收到的 event.data 属性就是在主线程中传入的值
img

2.3 接收 Worker 线程的消息

在 Worker 线程中,我们可以使用 self.postMessage() 方法向主线程发送消息。主线程可以通过监听 worker.onmessage 事件来接收这些消息。例如:

// worker.js
self.onmessage = (event) => {console.log('worker event: ', event)const { num } = event.data;const result = num + 1;self.postMessage({ value: result });
};
// 主线程
const worker = new Worker('worker.js');
worker.postMessage({ num: 10 });worker.onmessage = (event) => {console.log('main event: ', event);
};

运行后我们可以看到主线程中接收到了 Worker 线程发送的消息,其中 event.data 属性就是 Worker 线程中计算后的结果
img

这样我们就可以把主线程中的耗时操作放到 Worker 线程中执行,等待 Worker 线程执行完成后将结果返回给主线程,从而避免阻塞主线程,提升用户体验

2.4 关闭 Worker 线程

当 Worker 线程不再需要时,应该调用 worker.terminate() 方法来关闭它。这将释放 Worker 线程占用的资源。例如:

// 主线程
const worker = new Worker('worker.js');
worker.postMessage({ num: 10 });worker.onmessage = (event) => {console.log('main event: ', event);worker.terminate();
};

通过 Source 面板对比我们可以看到,调用 worker.terminate() 后 Worker 线程被销毁
img

3. 嵌入式 Worker 线程

有时候我们可能不想单独创建一个 JavaScript 文件来作为 Worker 线程的脚本,这时可以使用 Blob 对象来创建一个内联的 Worker 线程。例如:

const workerScript = `self.onmessage = (event) => {console.log('worker event: ', event)const { num } = event.data;const result = num + 1;self.postMessage({ value: result });};
`;const workerBlob = new Blob([workerScript], { type: 'text/javascript' });
const workerUrl = URL.createObjectURL(workerBlob);
const worker = new Worker(workerUrl);worker.postMessage({ num: 10 });worker.onmessage = (event) => {console.log('main event: ', event);
};

运行后同样可以看到 Worker 线程接收到了主线程的消息,主线程也接收到了 Worker 线程处理后的结果
img

4. 调试 Worker 线程

在浏览器的开发者工具中,可以通过 Source 面板查看和调试 Worker 线程。Worker 线程会显示在 Sources 面板的 Workers 部分,可以像调试主线程一样设置断点、查看变量等

  • 如果使用单独的 JavaScript 文件作为 Worker 线程的脚本,我们可以在 Source 面板通过文件名找到对应的 Worker 文件
    img

  • 如果使用内联的 Worker 线程脚本,Source 面板会有一个随机字符串作为 Worker 文件名,且每次重新加载文件名都会发生变化
    img

5. React 中使用 Worker 线程

import { useCreation } from 'ahooks';
import { Button } from 'antd';
import { useState } from 'react';const workerScript = `self.onmessage = (event) => {const { num } = event.data;const result = num + 1;self.postMessage({ value: result });};
`;export default function WebWorkerPage() {const [num, setNum] = useState(0);const worker = useCreation(() => {const workerBlob = new Blob([workerScript], { type: 'text/javascript' });const workerUrl = URL.createObjectURL(workerBlob);const worker = new Worker(workerUrl);worker.onmessage = (event) => {console.log('main event: ', event.data);setNum(event.data.value);};return worker;}, []);return (<div className="WebWorkerPage"><h4>{num}</h4><Button onClick={() => worker.postMessage({ num })}>Add</Button></div>);
}

示例中使用嵌入式 Worker 线程的方式,并通过 useCreation hook 来创建 Worker 线程,确保只创建一次 Worker 线程实例
点击 Add 按钮后,会向 Worker 线程发送主线程的 num 值,Worker 线程计算 num + 1(可替换为其他阻塞主线程的耗时操作),并将结果返回给主线程,主线程更新 num 的值并显示在页面上
img

参考文档:使用 Web Worker

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/962619.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙NEXT系列之精析NDK UI API(节点增删和属性设置) - 实践

鸿蒙NEXT系列之精析NDK UI API(节点增删和属性设置) - 实践2025-11-11 18:04 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !import…

通用cursor rules总结

所有项目通用规则 命名:base.mdc点击查看代码 --- description: globs: alwaysApply: true --- # 核心开发原则## 通用开发原则 - **可测试性**:编写可测试的代码,组件应保持单一职责 - **DRY 原则**:避免重复代码…

【JVS更新日志】开源框架升级vue 3、低代码、企业计划、智能BI及其他产品迎来新版本! - 实践

【JVS更新日志】开源框架升级vue 3、低代码、企业计划、智能BI及其他产品迎来新版本! - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impo…

银川西林瓶灌装旋盖机推荐2025,运行稳定连续8小时无故障

在制药、诊断试剂及高端保健品等细分领域,西林瓶灌装设备的运行稳定性已成为用户采购决策中的核心考量因素。据2024年行业调研数据显示,在连续工作8小时以上的生产场景中,设备无故障率对产线效率的影响权重高达67%。…

【ACM出版 | EI检索稳定】2025年人工智能、业务转型和数据科学创新国际学术会议(ICBTDS 2025)

人工智能(AI)正以前所未有的速度重塑全球商业格局,推动各行业业务模式转型和数据科学创新。【人工智能、大数据、机器学习、管理、经济相关主题稿件均可接收】 【稿件投稿录用可免费参会作口头报告】 2025年人工智能…

echarts 树形结构图实例

<html> <head><meta charset="UTF-8"> <title>用户关系图</title><style> </style><script type="text/javascript" src="https://fastly.jsd…

pg_hba.conf配置里peer,indent和md5的区别

在 PostgreSQL 的 pg_hba.conf配置文件中,peer、ident和 md5是三种不同的认证方法。以下是它们的详细区别: 1. peer​ 认证方法 特点: 仅适用于本地连接(local connection type) 基于操作系统用户身份进行认证 不…

基于Simulink的双电机PID控制仿真实现方案

基于Simulink的双电机PID控制仿真实现方案,包含S函数建模、阶跃信号输入和可视化分析:一、系统架构设计二、模块实现 1. 电机动力学S函数(motor_sfun.m) function [sys,x0,str,ts] = motor_sfun(t,x,u,flag) switc…

锡林郭勒西林瓶灌装清洗耗材月成本分析?查行情享优惠

近年来,随着制药装备智能化水平持续提升,西林瓶灌装设备及相关配套耗材的采购成本正逐步趋于理性。行业普遍呈现出“高配置、低门槛”的价格趋势,性价比已成为用户选购西林瓶灌装生产线的核心考量指标。尤其在清洗环…

AI Agent OS 探索有价值的论文分析(1):Sleep-time Compute

Sleep-time Compute 分析 1.摘要 论文信息论文地址:[2504.13171v1] Sleep-time Compute: Beyond Inference Scaling at Test-time开源项目:GitHub - letta-ai/sleep-time-compute: accompanying material for sleep-…

Linux内核架构浅谈26-Linux实时进程调度:优先级反转与解决实用的方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

宏定义的高级应用

define KEY3_PORT GPIOE define KEY3_PIN GPIO_Pin_1 define KEY3_EXTI_PORTSOURCE EXTI_PortSourceGPIOE define KEY3_EXTI_PINSOURCE EXTI_PinSource1 define KEY3_EXTI_Line EXTI_Line1 define KEY4_PORT …

被问性能后,我封装了这个 PHP 错误上报工具

介绍 PHP 日志库 hejunjie/lazylog 的实现:用 proc_open / exec 伪异步上报异常,支持本地日志与常驻内存框架优化,轻量高效,适合生产环境使用最近我把自己常用的一套错误上报逻辑封装成了一个 Composer 包,叫 ​h…

公众号中的贴纸素材有什么作用?在哪里找?

不知道你有没有这种感觉:公众号文章写好了,排版也收拾得挺干净,但总觉得页面有点“素”,少了点能抓住眼球的小趣味。 这时候,贴纸素材就派上用场了。 你可能已经用过一些贴纸,比如在段落之间加一条可爱的分割线,…

国标GB28181算法算力平台EasyGBS:深度解析全场景视频调阅功能与行业实战应用

国标GB28181算法算力平台EasyGBS:深度解析全场景视频调阅功能与行业实战应用在视频监控全面联网、智能化升级的时代,单纯的点对点监控已无法满足复杂业务的需求。核心诉求在于:如何在一个平台上,随时随地、高效稳定…

2025出国留学机构综合实力榜:排名前十的留学中介特色分析

2025出国留学机构综合实力榜:排名前十的留学中介特色分析Posted on 2025-11-11 17:46 打不死的小强996 阅读(0) 评论(0) 收藏 举报在当前多元化的留学环境下,选择一家合适的出国留学中介成为许多家庭的重要决策…

公众号怎么起爆款标题?有什么好用的工具?

不知道你有没有这种感觉:公众号文章内容写得挺用心,但最后却卡在了起标题这一步。脑子里想来想去,就是那几个老套路,觉得没啥吸引力。 说实话,一个好的标题,真的决定了文章能不能被打开。我之前也特别头疼这个,…

邢台西林瓶灌装机优选指南:聚焦资质、案例与售后

在邢台地区,制药与生物制剂企业近年来对西林瓶灌装设备的需求持续增长。随着本地医药产业链的完善,越来越多中小型药企和科研机构开始关注设备采购中的价格适配性问题。根据2024年华北区域制药装备用户调研数据显示,…

基于SpringBoot+Vue的个人理财系统管理系统设计与建立【Java+MySQL+MyBatis完整源码】

基于SpringBoot+Vue的个人理财系统管理系统设计与建立【Java+MySQL+MyBatis完整源码】pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; …

python使用PyInstaller打包成exe

PyInstaller是目前最流行的Python打包工具之一,其安装过程极为简便。在Windows系统上,只需通过pip命令即可完成安装: pip install pyinstaller 安装完成后,可通过pyinstaller --version验证安装是否成功。对于国内…