webWorker基本用法

news2024/11/26 6:25:06

我们都知道js是一个单线程的语言,当线程堵塞时,可能会导致页面无法正常交互,如一些复杂的可视化处理。即使是异步处理,也只是将其暂存到任务队列中去,等主线程执行完后依然会从任务队列中取过去。

为此,js提供了一种多线程效果的处理方式--webWorker,下面来用一段实力来展示:

基本示例(这里在一个vue项目中展示)

1.先创建一个webWorker对应的js文件

注:由于webworker构造函数接收的路径需要是线上的地址,因此在开发过程中可以放到public文件夹中(如example.js)这样,通过 项目启动地址+文件名即可访问该文件。

这样通过http://127.0.0.1:5173/example.js 即可访问该文件,并看到该文件内容:

2.在想要使用webWorker的方法中,创建一个webWorker对象(参数为上面的地址,本示例中的http://127.0.0.1:5173/example.js);不用本地地址的原因后续会说。

<button @click="startWebWorker">点我触发webWorker</button>
startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js")
},

这样,当点击此按钮时,会调用example.js中的脚本内容输出“hello world”。

3.postMessage方法:

通过postMessage可以向webWorker中传递参数(不可为函数):

startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js")
  myWorker.postMessage("hello webWorker");
},

4.接收传过来的数据:

这里可以通过监听message事件来获取到数据。(webWorker对应文件中使用self进行postMessage等相关操作)

example.js中:

// console.log("hello world")
self.addEventListener("message", (res) => {
    console.log(res.data); // 输出 hello webWorker
})

(ps,也可以使用self.onmessage来获取)

5.反向传递信息

其原理与上面的类似,同样使用postMessage,与监听message来实现:

示例vue文件中的方法:

startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js")
  myWorker.postMessage("发送的信息:hello webWorker");
  myWorker.addEventListener("message", (res) => {
    console.log("返回的信息:" + res.data)
  })
},

example.js中:

// console.log("hello world")
self.addEventListener("message", (res) => {
    console.log(res.data); // 输出 hello webWorker
    self.postMessage("nice to meet you too!");
})

结果:

6.补充:

比如说 public/example.js 中想要使用 public/test.js 中的方法:

 public/test.js:

function testFun() {
    console.log('我是testFun')
}

 public/example.js:(这里直接这样引用会报错)

import "./test.js"
testFun();

需改为以下引发:

// import "./test.js"
importScripts("http://127.0.0.1:5173/test.js")
testFun()

当然有一种例外,就是test.js中使用的es6的module:

 public/test.js:

export function testFun() {
    console.log('我是testFun')
}

报错:Uncaught SyntaxError: Cannot use import statement outside a module

此时就不能用importScripts了,需要在创建webWorker对象时声明type为module

示例vue文件中的 创建一个webWorker对象 部分:

// 创建一个webWorker对象
let myWorker = new Worker("http://127.0.0.1:5173/example.js", {
    type: "module"
})

 public/example.js:

import { testFun } from "./test.js"
// importScripts("http://127.0.0.1:5173/test.js")
testFun()

这样就生效了。

webWorker注意事项

1.webWorker文件中的方法不可操作节点。

2.postMessage方法不可传递function方法。

3.new Worker参数不可为本地文件,可使用线上地址(如发布出去)。

4.在webWorker文件中若想使用第三方库的方法(如导出excel),可以通过cdn引入,或者将node_modules关键文件以同样方式(放入public或发布)引入。

单线程堵塞处理实例

1.堵塞简单示例,最简单的,遍历百亿次(电脑好可以更多,根据务必电脑情况斟酌):

<button @click="startWebWorker">遍历一亿次</button>
信息:<input />
startWebWorker() {
  let total = 0
  for(let i = 0; i< 10000000000; i++) {
    total++;
  }
  console.log("结果是:" + total);
},

在结果输出前,你会发现输入框处于无法交互状态,整个页面都被堵塞所影响了,这个是异步也很难解决的问题。

因此,这里可以借助webWorker来实现:

startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js");
  myWorker.postMessage("开始遍历");
  myWorker.onmessage = (res) => {
    console.log("结果是:" + res.data);
  }
},

 public/example.js:

self.addEventListener("message", (res) => {
    if(res.data == "开始遍历") {
        let total = 0
        for(let i = 0; i< 10000000000; i++) {
          total++;
        }
        self.postMessage(total)
    }
})

这样,堵塞就因 webWorker多线程 的缘故而不会影响页面(如:输入框)的正常交互了。

希望本文会对您有所帮助 ^_^ ~

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

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

相关文章

一文学习Android中的Property

在 Android 系统中&#xff0c;Property 是一种全局的键值对存储系统&#xff0c;允许不同组件和进程间以轻量级的方式进行数据传递。它主要用于系统配置、状态标识等场景&#xff0c;使得不同进程能够通过属性的设置或获取来通信。property 的核心特性是快速、高效&#xff0…

使用PEFT在多个AMD GPU上进行StarCoder的指令微调

Instruction fine-tuning of StarCoder with PEFT on multiple AMD GPUs — ROCm Blogs 2024年4月16日&#xff0c;由 Douglas Jia撰写。 在这篇博客中&#xff0c;我们将向您展示如何使用指令-答案对数据集在AMD GPU上微调StarCoder基础模型&#xff0c;以便它能够根据指令生…

后台管理系统窗体程序:文章管理 > 文章列表

目录 文章列表的的功能介绍&#xff1a; 1、进入页面 2、页面内的各种功能设计 &#xff08;1&#xff09;文章表格 &#xff08;2&#xff09;删除按钮 &#xff08;3&#xff09;编辑按钮 &#xff08;4&#xff09;发表文章按钮 &#xff08;5&#xff09;所有分类下拉框 &a…

微软的新模拟器将为 Windows on Arm 带来更多游戏

微软正在测试一项重大的 Windows on Arm 更新&#xff0c;以便让更多 x64 软件和游戏在配备高通 Snapdragon X Elite 或 X Plus 处理器的 Copilot Plus PC 上的 Prism 仿真下运行。 该功能是 Windows 11 Insider Preview Build 27744 的一部分&#xff0c;已向 Canary Channel …

NVR小程序接入平台/设备EasyNVR多品牌NVR管理工具/设备汇聚公共资源场景方案全析

随着信息技术的飞速发展&#xff0c;视频监控已经成为现代社会安全管理和业务运营不可或缺的一部分。特别是在公共资源管理方面&#xff0c;视频监控的应用日益广泛&#xff0c;涵盖了智慧城市、智能交通、大型企业以及校园安防等多个领域。NVR小程序接入平台EasyNVR作为一款功…

从单层到 MVC,再到 DDD:架构演进的思考与实践

引言 在日常开发中&#xff0c;我们之前工作中经常接手的大多数都是传统 MVC 架构体系的项目。然而&#xff0c;随着现在分布式和微服务架构的普及&#xff0c;越来越多的项目开始重构、拆分&#xff0c;传统的 MVC 架构也逐渐向 DDD 架构演进。为什么需要将传统架构重构为 DD…

CDN到底是什么?

文章目录 CDN到底是什么&#xff1f;一、引言二、CDN的基本概念1、CDN的定义2、CDN的作用3、代码示例&#xff1a;配置CNAME记录 三、CDN的工作原理1、请求流程2、代码示例&#xff1a;DNS解析过程3、完整的CDN工作流程 四、总结 CDN到底是什么&#xff1f; 一、引言 在互联网…

uniapp—android原生插件开发(3Android真机调试)

本篇文章从实战角度出发&#xff0c;将UniApp集成新大陆PDA设备RFID的全过程分为四部曲&#xff0c;涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程&#xff0c;轻松应对安卓原生插件开发与打包需求&#xff01; 一、打包uniapp资源包&#xff1a; 打包…

嵌入式采集网关(golang版本)

为了一次编写到处运行&#xff0c;使用纯GO编写&#xff0c;排除CGO&#xff0c;解决在嵌入式中交叉编译难问题 硬件设备&#xff1a;移远EC200A-CN LTE Cat 4 无线通信模块&#xff0c;搭载openwrt操作系统&#xff0c;90M内存

IDEA中maven更新pom文件后使其生效(自动 + 手动)

pom文件更新后默认是不生效的&#xff0c;需要手动刷新maven&#xff0c;即点击Reload Project&#xff0c;注意尽量不要用最上面那个Reload all project&#xff0c;这样的话刷新会很慢&#xff0c;因为会对整个项目Reload Project 如果懒得每次手动Reload&#xff0c;那么可…

单调栈—acwing

一、题目&#xff1a; AcWing 830. 单调栈 - AcWing 暴力算法思想 双指针算法&#xff0c;本质上是比较操作&#xff0c;两个循环&#xff0c;时间复杂度高。通过栈可以一次遍历。 可以知道&#xff0c;只要前面有一个小于我的数&#xff0c;就可以。如果前面的数&#xff…

Linux内核中IRQ Domain的结构、操作及映射机制详解

往期内容 本专栏往期内容&#xff0c;interrtupr子系统&#xff1a; 深入解析Linux内核中断管理&#xff1a;从IRQ描述符到irq domain的设计与实现 pinctrl和gpio子系统专栏&#xff1a; 专栏地址&#xff1a;pinctrl和gpio子系统 编写虚拟的GPIO控制器的驱动程序&#xff1a;…

C++ 继承:代码传承的魔法棒,开启奇幻编程之旅

文章目录 一.继承的概念及定义1.1继承的概念1.2继承类1.2.1继承方法 1.3继承模板 二.基类和派生类的转换三.继承中的作用域四.派生类的默认成员函数4.1默认成员函数的行为4.2实现一个无法被继承的类 五.继承与友元六.继承与静态成员七.多继承和菱形继承7.1多继承和菱形继承7.2虚…

无人车之编队控制算法篇

一、编队控制算法概述 无人车编队控制算法旨在实现多辆无人车之间的协同行驶&#xff0c;保持预定的队形和间距&#xff0c;以应对各种复杂环境和任务需求。该算法通常包括队形生成、队形保持、队形变换和编队模式切换等关键步骤。 二、编队控制算法的核心要素 队形生成&…

【大数据学习 | kafka高级部分】kafka的数据同步和数据均衡

1. 数据同步 通过上图我们发现每个分区的数据都不一样&#xff0c;但是三个分区对外的数据却是一致的 这个时候如果第二个副本宕机了 但是如果是leader副本宕机了会发生什么呢&#xff1f; 2. 数据均衡 在线上程序运行的时候&#xff0c;有的时候因为上面副本的损坏&#xff…

计算机网络——TCP篇

TCP篇 基本认知 TCP和UDP的区别? TCP 和 UDP 可以使用同一个端口吗&#xff1f; 可以的 传输层中 TCP 和 UDP在内核中是两个完全独立的软件模块。可以根据协议字段来选择不同的模块来处理。 TCP 连接建立 TCP 三次握手过程是怎样的&#xff1f; 一次握手:客户端发送带有 …

Xserver v1.4.2发布,支持自动重载 nginx 配置

Xserver——优雅、强大的 php 集成开发环境 本次更新为大家带来了更好的用户体验。 &#x1f389; 下载依赖组件时&#xff0c;显示进度条&#xff0c;展示下载进度。 &#x1f389; 保存站点信息和手动修改 vhost 配置文件之后&#xff0c;自动重载 nginx 配置 &#x1f41e…

Day107:代码审计-PHP模型开发篇MVC层RCE执行文件对比法1day分析0day验证

知识点&#xff1a; 1、PHP审计-MVC开发-RCE&代码执行 2、PHP审计-MVC开发-RCE&命令执行 3、PHP审计-MVC开发-RCE&文件对比 MVC 架构 MVC流程&#xff1a; Controller截获用户发出的请求&#xff1b;Controller调用Model完成状态的读写操作&#xff1b;Contr…

飞书API-获取tenant_access_token

1.在飞书工作台创建应用&#xff0c;跳到开发者后台&#xff0c;选创建企业自建应用 2.设置并发布应用 必须要发布应用才可以开始使用了&#xff01;&#xff01;&#xff01; 3.调用获取token的API 参考链接&#xff1a; 开发文档 - 飞书开放平台https://open.feishu.cn/do…

推荐 4 个 YYDS 的开源项目!

如下是本期盘点的几个好玩有趣的开源项目&#xff0c;目录&#xff1a; 1. 网页截屏转为代码 2. 将文档转为 Markdown 和 JSon 格式 3. 帮你写代码的 AI 助手 4. 开源 RAG 工具 01 网页截屏转为代码 screenshot-to-code 利用先进的大模型识别屏幕截图中的 UI 元素、布局以及其他…