js中【Worker】相关知识点详细解读
什么是 JavaScript 中的 Worker?
JavaScript 中的 Worker 是一个可以在后台线程中运行代码的 API,这样可以避免主线程(通常是 UI 线程)被阻塞。使用 Worker 时,JavaScript 可以在多线程环境中工作,解决了单线程的瓶颈问题。
通常情况下,JavaScript 是单线程的,也就是所有的代码(包括 DOM 操作和事件处理等)都在同一个线程里执行。如果某段代码需要大量计算,或者运行时间过长,会阻塞整个页面,导致界面卡顿甚至崩溃。Worker 提供了一种将复杂或耗时的任务分配到后台线程执行的方法。
Worker 的核心特点:
- 后台线程:Worker 代码在与主线程不同的后台线程中执行。
- 无阻塞:可以处理计算密集型任务而不阻塞主线程。
- 无 DOM 访问:Worker 不能直接访问主线程中的 DOM(文档对象模型),它们只能通过消息与主线程进行通信。
- 消息传递:主线程和 Worker 通过
postMessage()和onmessage事件来交换数据。
基本使用
JavaScript 中有几种 Worker,不同 Worker 的用法略有区别:
- Web Worker:标准的 Worker,用于网页中的后台线程。
- Service Worker:专门用于网络请求的 Worker。
- Shared Worker:可以被多个脚本或页面共享的 Worker。
下面我们先来重点讲解 Web Worker 的使用。
创建 Web Worker
你需要创建一个单独的 JavaScript 文件作为 Worker 的入口点,然后在主线程中启动 Worker。假设我们有一个需要在 Worker 中运行的文件 worker.js,并且有一个主线程脚本 main.js。
1. 创建 Worker 文件
首先,我们编写一个 worker.js 文件,里面包含 Worker 将要执行的代码:
// worker.js
// Worker 内部不能访问 DOM,但可以执行任何复杂的计算任务
self.onmessage = function(event) {// 接收主线程发送的数据const number = event.data;// 进行耗时的计算任务,比如计算一个数的平方const result = number * number;// 将结果返回给主线程self.postMessage(result);
};
self 是 Worker 内部的全局对象,它相当于主线程中的 window,但没有 UI 相关的 API(比如不能操作 DOM)。onmessage 监听主线程发送的数据,而 postMessage 用于将结果返回给主线程。
2. 在主线程中创建 Worker
接下来,我们在 main.js 中创建并使用 Worker:
// main.js
// 创建一个新的 Worker 实例,指向 worker.js 文件
const worker = new Worker('worker.js');// 主线程向 Worker 发送消息
worker.postMessage(10); // 发送数字 10,Worker 将计算 10 的平方// 监听 Worker 返回的消息
worker.onmessage = function(event) {console.log('从 Worker 接收到的数据:', event.data); // 输出: 100
};// 错误处理
worker.onerror = function(error) {console.error('Worker 出现错误:', error.message);
};
在这个例子中,postMessage() 方法用于从主线程向 Worker 发送数据,onmessage 方法用于监听 Worker 处理完任务后返回的数据。Worker 可以用于运行像计算密集型任务(如数学运算、数据处理)而不会影响主线程的流畅性。
3. 停止 Worker
当任务完成后,可以选择手动终止 Worker:
// 终止 Worker
worker.terminate();
一旦 terminate() 被调用,Worker 将立即停止执行,并且不会再处理任何任务。适当终止 Worker 可以节省系统资源。
使用 Worker 传递复杂数据
Worker 不仅可以处理简单的数据类型(如数字和字符串),还可以传递更复杂的数据(如对象和数组)。这里我们扩展上面的例子,传递一个对象到 Worker 并让 Worker 处理它:
// worker.js
self.onmessage = function(event) {const data = event.data;// 假设传入的是一个对象,我们对它的属性进行处理const result = {squared: data.number * data.number,doubled: data.number * 2};// 返回结果给主线程self.postMessage(result);
};
// main.js
const worker = new Worker('worker.js');// 向 Worker 发送一个对象
worker.postMessage({ number: 5 });// 监听 Worker 返回的对象
worker.onmessage = function(event) {const result = event.data;console.log('平方:', result.squared); // 输出: 25console.log('翻倍:', result.doubled); // 输出: 10
};
Worker 的局限性
- 无法访问 DOM:Worker 不能直接操作 DOM。如果你需要进行与 UI 相关的操作,必须通过
postMessage()与主线程通信。 - 同源策略:Worker 脚本必须与页面脚本同源,不能跨域加载 Worker 文件。
- 性能开销:虽然 Worker 可以提高性能,但创建 Worker 本身也有一定的开销,特别是创建大量 Worker 时会增加资源消耗。
- 脚本文件:创建 Worker 必须通过外部文件,不能直接在同一个脚本内定义 Worker 的代码。
实际场景中的应用
- 处理大数据:Worker 常用于数据密集型计算(如图像处理、文件解析、复杂算法)。
- 保持 UI 流畅:在不阻塞用户界面的情况下执行长时间运行的任务。
- 实时数据处理:通过 Worker 进行后台的数据处理、文件操作等,不会影响页面的响应速度。
示例:使用 Worker 处理大量数据
// worker.js
self.onmessage = function(event) {const data = event.data;const processedData = data.map(item => item * 2); // 模拟处理大量数据self.postMessage(processedData);
};
// main.js
const worker = new Worker('worker.js');// 模拟大量数据
//'-'是占位符,表示不关心这个参数的值,它是Array.from方法的第一个参数,即生成数组时当前元素的值
//i是第二个参数,表示当前数组元素的索引
const largeArray = Array.from({ length: 1000000 }, (_, i) => i);worker.postMessage(largeArray);worker.onmessage = function(event) {console.log('处理完成的数据:', event.data); // 将显示处理后的数据
};
在这个例子中,我们生成了一个包含百万个元素的数组并交给 Worker 处理。处理完成后,Worker 将返回一个新的数组给主线程。
总结
JavaScript 中的 Worker API 是一种强大的工具,能够帮助开发者处理耗时任务,避免页面卡顿。它主要通过后台线程执行代码,避免阻塞主线程,并通过消息传递与主线程进行通信。
关键点回顾:
- Worker 是运行在后台线程中的脚本,主线程与 Worker 通过
postMessage()和onmessage通信。 - Worker 不能访问 DOM,但适合用于计算密集型任务。
- 创建 Worker 有一定开销,建议合理使用,尤其是在多 Worker 环境下。
可以尝试将复杂计算任务移到 Worker 中,这样可以提高用户体验并保持应用的流畅性。
相关文章:
js中【Worker】相关知识点详细解读
什么是 JavaScript 中的 Worker? JavaScript 中的 Worker 是一个可以在后台线程中运行代码的 API,这样可以避免主线程(通常是 UI 线程)被阻塞。使用 Worker 时,JavaScript 可以在多线程环境中工作,解决了单…...
使用Apify加载Twitter消息以进行微调的完整指南
# 使用Apify加载Twitter消息以进行微调的完整指南## 引言在自然语言处理领域,微调模型以适应特定任务是提升模型性能的常见方法。本文将介绍如何使用Apify从Twitter导出聊天信息,以便进一步进行微调。## 主要内容### 使用Apify导出推文首先,我…...
【C++算法】滑动窗口
长度最小的子数组 题目链接: 209. 长度最小的子数组 - 力扣(LeetCode)https://leetcode.cn/problems/minimum-size-subarray-sum/description/ 算法原理 代码步骤: 设置left0,right0设置sum0,len0遍历l…...
(c++)猜数字(含根据当前时间生成伪随机数代码)
#include<iostream> #include<ctime>/*用srand((unsigned int)time(NULL));要包含这个头文件,如果没有这两个,rand()函数会一直生成42这个伪随机数。*/using namespace std;int main() {srand((unsigned int)time(NULL));//种子,…...
优化批处理流程:自定义BatchProcessorUtils的设计与应用
优化批处理流程:自定义BatchProcessorUtils的设计与应用 | 原创作者/编辑:凯哥Java | 分类:个人小工具类 在我们开发过程中,处理大量的数据集是一项常见的任务。特别是在数据库操作、文件处理或者…...
Framebuffer应用编程
目录 前言 LCD操作原理 涉及的 API 函数 open函数 ioctl 函数 mmap 函数 Framebuffer程序分析 源码 1.打开设备 2.获取LCD参数 3.映射Framebuffer 4.描点函数 5.随便画几个点 上机实验 前言 本文介绍LCD的操作原理和涉及到的API函数,分析Framebuffer…...
MongoDB根据字段内容长度查询语句
db.getCollection("qlzx_penalties_business_raw").find({$expr: {$lt: [{ $strLenCP: "$punish_name" }, 5]},"punish_name_type" : "机构", "source_data" : /中国/,})解释: 1-"source_data" : /中…...
Android中的单例模式
在Android开发中,单例模式(Singleton Pattern)是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。单例模式在需要控制资源访问、管理共享资源或配置信息的场景下特别有用。在Androi…...
python做游戏好用吗
Python做游戏是完全可以的,而且也非常简单,有一个专门针对游戏开发的平台(模块)—pygame,允许开发人员快速设计游戏而又摆脱了低级语言的束缚,下面我简单介绍一下这个模块的安装和使用: 1、首先…...
常用游戏运行库下载
包含以下资源: DirectX Repair.exe DirectX Repair(Enhanced Edition). vcredist C2013 x64.exe 微软常用运行库合集 下载链接...
(1)CLIP
CLIP 概述1. 训练与推理2. 最终效果与局限性3.后续应用3.1 DALL-E3.2 ActionCLIP3.3 CLIP-Event 概述 CLIP:contrastive language-image pretraining 利用文本的监督信号训练一个迁移能力特别强的视觉模型 传统的视觉模型,人工标注图像,那么…...
MongoDB高可用和分片集群知识
一、MongoDB实现高可用 1. MongoDB复制集(Replication Set) 在实际生产中,MongoDB要实现高可用,以免MongoDB单实例挂了,服务不可用。MongoDB实现高可用是以MongoDB复制集的形式实现,和集群部署概念相同,MongoDB复制集…...
【Python日志功能】一.日志基础与基本配置
文章目录 相关链接第一篇:日志基础与基本配置1 日志的概念与用途2 Python logging 模块介绍3 日志级别4 配置日志格式和输出位置4.1 配置日志格式4.2 配置输出位置 5 实验:基本日志配置和输出实验1:基本日志配置实验2:使用配置文件…...
深圳铨顺宏科技展邀您体验前沿人工智能技术
我们诚挚地邀请您参加即将举行的展会,探索RFID技术在资产与人员管理中的广泛应用。这些展会将为您提供一个深入了解前沿技术和创新解决方案的机会。 东莞台湾名品博览会(东莞台博会)展会时间:9月5日至8日。此次展会展示了来自台湾…...
Lombok:Java开发者的代码简化神器【后端 17】
Lombok:Java开发者的代码简化神器 在Java开发中,我们经常需要编写大量的样板代码,如getter、setter、equals、hashCode、toString等方法。这些代码虽然基础且必要,但往往占据了大量开发时间,且容易在属性变更时引发错误…...
[linux]GCC G++官方源码国内下载地址汇总
【GCC介绍】 GCC(GNU Compiler Collection,GNU编译器套件)是由GNU项目开发的一套编程语言编译器,也是GNU计划的关键部分。它最初作为GNU C Compiler(GNU C语言编译器)出现,但随着时间的推移&…...
部署opengauss5.0.3,细节满满
部署opengauss5.0.3 1.关闭安全服务 修改/etc/selinux/config文件中的“SELINUX”值为“disabled”。临时关闭selinux setenforce 0 查看selinux状态 getenforce2.host配置 [rootcentos79 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 local…...
面试题总结(四) -- STL与算法篇
面试题总结(四) – STL与算法篇 文章目录 面试题总结(四) -- STL与算法篇<1> 请列举 C STL 中常用的容器(如 vector、list、map 等)及其特点。<2> 如何在 C 中使用 STL 算法(如排序、查找等)?<3> 解…...
HashSet及其实现原理
目录 一、Set二、HashSet三、HashSet的实现原理四、HashSet的线程安全与顺序1、线程安全2、有序性 一、Set Set 接口是 java.util 包下的一个集合接口,它继承自 Collection 接口。Set 接口定义了一个不允许包含重复元素的集合。Set 接口的实现类主要有 HashSet、Lin…...
反序列化漏洞练习1
根据代码可以看出来sis类只是接收了参数cmd,下边是通过get获得cmd的值,所以可以在序列化过程中直接为cmd赋值。 根据源码编写序列化代码 <?php class sis{public $cmdsystem("whoami");?>;public function __wakeup(){eval($this-&g…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
