在Vue中使用Web Worker详细教程

1.什么是Web Worker?

        Web Worker 是2008年h5提供的新功能,每一个新功能都是为了解决原有技术的的痛点,那么这个痛点是什么呢?

1.1 JavaScript的单线程

JavaScript 为什么要设计成单线程

  • 这与js的工作内容有关:js只是用来去做一些用户交互,并呈现效果内容。
  • 如果js是多线程,线程一将dom元素的背景色改成红色,线程二将dom元素的背景色改为绿色,那么,到底上红色还是绿色呢?

        但是随着前端的高速发展,前端承担着越来越多的功能,有时需要执行一些复杂的计算任务,但是JavaScript的单线程一旦执行某个耗时的任务,后面的任务都会阻塞,如果在前端能够做多线程的操作,那不就解决这个问题啦,于是,于是Web Worker就应运而生了。

1.2 Web Worker的概念

        Web Worker可以创建另外的线程去做一些操作(比如执行一些耗时的操作),这个操作不影响js主线程(比如UI渲染)的执行 。Web Worker为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。此外,他们可以使用XMLHttpRequest执行 I/O (尽管responseXML和channel属性总是为空)。一旦创建,一个 worker 可以将消息发送到创建它的 JavaScript 代码,通过将消息发布到该代码指定的事件处理程序(反之亦然)......

使用 Web Workers - Web API 接口参考 | MDN

1.3 Web Worker的价值

        Web Worker创建的一些辅助线程,分别去帮主线程分担一些复杂的、耗时的js运算,这样的话,主线程后续的代码执行就不会阻塞,当辅助线程计算出复杂耗时运算结果后,再与主线程通信,将计算出的结果告知主线程。

Web Worker新技术价值,简而言之:提升前端代码运算执行效率 

1.4 Web Worker的限制

  • Web Worker, worker 运行在另一个全局上下文中, 有它自己的执行上下文
  • 不能使用 window 对象的默认方法和属性,不能直接操作 DOM 节点。

1.5 Web Worker 和主线程之间的通信方式

        workers 和主线程间的数据传递,双方都使用 postMessage() 方法发送各自的消息,使用 onmessage 事件处理函数来响应消息(消息被包含在 message 事件的 data 属性中)。这个过程中数据并不是被共享而是被复制。

2. Web Worker 原生用法

2.1 独享Worker

        一个专用 worker 仅能被生成它的脚本所使用

2.1.1 创建一个专用worker

const myWorker = new Worker("worker.js");
  •  使用构造器创建worker对象,参数是一个 JavaScript 文件——这个文件包含将在 worker 线程中运行的代码。

2.1.2 主线程与worker之间的通信

  • 主线程向worker发送信息
myWorker.postMessage([first.value, second.value]);
  • 主线程监听worker信息
myWorker.onmessage = (e) => {console.log(e.data);
};
  • worker监听主线程信息/worker向主线程发送信息 
onmessage = function(e) {postMessage(e.data);
}

2.1.3 终止worker

myWorker.terminate();

        worker 线程会被立即终止。 

2.1.4 在worker中引入外部脚本

         Worker 线程能够访问一个全局函数 importScripts() 来引入脚本,该函数接受 0 个或者多个 URI 作为参数来引入资源

importScripts(); /* 什么都不引入 */
importScripts("foo.js"); /* 只引入 "foo.js" */
importScripts("foo.js", "bar.js"); /* 引入两个脚本 */
importScripts("//example.com/hello.js"); /* 你可以从其他来源导入脚本 */

2.2 独享worker应用案例 

        将你输入的 2 个数字作乘法。输入的数字会发送给一个专用 worker,由专用 worker 作乘法后,再返回给页面进行展示。

index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width" /><title>Web Workers basic example</title></head><body><div class="controls" tabindex="0"><form><div><label for="number1">Multiply number 1: </label><input type="text" id="number1" value="0" /></div><div><label for="number2">Multiply number 2: </label><input type="text" id="number2" value="0" /></div></form><p class="result">Result: 0</p></div><script>const first = document.querySelector('#number1');const second = document.querySelector('#number2');const result = document.querySelector('.result');if (window.Worker) {// 1.创建一个worker 指定一个js脚本的 URI 来执行 worker 线程const myWorker = new Worker("worker.js");[first, second].forEach(input => {input.onchange = function() {// 2.主线程给worker发送数据,参数是数组格式myWorker.postMessage([first.value, second.value]);console.log('Message posted to worker');}})// 3.主线程监听worker传递过来的信息//  数据本身在e.data中myWorker.onmessage = function(e) {result.textContent = e.data;console.log('Message received from worker');}} else {console.log('Your browser doesn\'t support web workers.');}</script></body>
</html>

worker.js

// 1.监听主线程发过来的数据
onmessage = function(e) {console.log('Worker: Message received from main script');const result = e.data[0] * e.data[1];if (isNaN(result)) {
// 2.给主线程发送数据postMessage('Please write two numbers');} else {const workerResult = 'Result: ' + result;console.log('Worker: Posting message back to main script');postMessage(workerResult);}
}

 备注: 

  • 在主线程中使用时,onmessage 和 postMessage() 必须挂在 worker 对象上
  • 而在 worker 中使用时不用这样做。原因是,在 worker 内部,worker 是有效的全局作用域,相当于js环境中的window。

2.2 共享Worker

一个共享 worker 可以被多个脚本使用——即使这些脚本正在被不同的 window、iframe 或者 worker 访问。

示例:

        在这个示例中有 2 个 HTML 页面,每个页面所包含一个 JavaScript 代码,这两个脚本使用同一个 worker 来完成实际需要的运算。

  • 页面1:
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width" /><title>Shared Workers basic example</title></head><body><h1>共享Worker示例-页面1</h1><div class="controls" tabindex="0"><form><div><label for="number1">Multiply number 1: </label><input type="text" id="number1" value="0" /></div><div><label for="number2">Multiply number 2: </label><input type="text" id="number2" value="0" /></div></form><p class="result1">Result: 0</p><p><a href="index2.html" target="_blank">Go to 示例-页面2</a></p></div><script>const first = document.querySelector("#number1");const second = document.querySelector("#number2");const result1 = document.querySelector(".result1");if (!!window.SharedWorker) {// 1.创建一个共享workerconst myWorker = new SharedWorker("worker.js"); // 4.使用端口对象调用postMessage给worker发送信息first.onchange = function () {myWorker.port.postMessage([first.value, second.value]);console.log("Message posted to worker");};second.onchange = function () {myWorker.port.postMessage([first.value, second.value]);console.log("Message posted to worker");};// 2.通过port端口与worker通信// 3.通过onmessage显式的打开端口连接myWorker.port.onmessage = function (e) {result1.textContent = e.data;console.log("Message received from worker");console.log(e.lastEventId);};}</script></body>
</html>
  • 页面2:创建worker和与worker的过程和页面1是一样的
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width" /><title>Shared Workers basic example</title></head><body><h1>共享Worker示例-页面2</h1><div class="controls" tabindex="0"><form><div><label for="number3">Square number: </label><input type="text" id="number3" value="0" /></div></form><p class="result2">Result: 0</p></div><script>const squareNumber = document.querySelector("#number3");const result2 = document.querySelector(".result2");if (!!window.SharedWorker) {// 1.创建一个共享workerconst myWorker = new SharedWorker("worker.js"); // 4.使用端口对象调用postMessage给worker发送信息squareNumber.onchange = function () {myWorker.port.postMessage([squareNumber.value, squareNumber.value]);console.log("Message posted to worker");};// 2.通过port端口与worker通信// 3.通过onmessage显式的打开端口连接myWorker.port.onmessage = function (e) {result2.textContent = e.data;console.log("Message received from worker");};}</script></body>
</html>
  • worker.js 
// 在父级线程中,设置 onmessage 事件处理函数后
// 会执行worker的onconnect时间
onconnect = function (event) {// 1.使用事件的 ports 属性来获取端口并存储在变量中const port = event.ports[0];// 2.为端口添加一个 onmessage 处理函数用来做运算并回传结果给主线程port.onmessage = function (e) {const workerResult = `Result: ${e.data[0] * e.data[1]}`;port.postMessage(workerResult);};
};

3.在Vue项目中使用 Web Worker

        在vue项目里面不能直接使用Web Worker,要使用Web Worker有两种方式,一种是使用worker-loader,一种是使用vue-worker,下面对这两种方法详细介绍。

3.1 worder-loader

使用Webpack中的worker-loader插件去解析Web worker,并且在vue.config.js中去做相应配置。

3.2 vue-worker

参考:

使用 Web Workers - Web API 接口参考 | MDN

Web Worker 使用教程 - 阮一峰的网络日志

性能优化之使用vue-worker插件(基于Web Worker)开启多线程运算提高效率 - 掘金

Web Worker入门及在 Vue 中如何使用 - 掘金

https://www.npmjs.com/package/vue-worker?activeTab=readme

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

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

相关文章

PiflowX-MysqlCdc组件

MysqlCdc组件 组件说明 MySQL CDC连接器允许从MySQL数据库读取快照数据和增量数据。 计算引擎 flink 组件分组 cdc 端口 Inport&#xff1a;默认端口 outport&#xff1a;默认端口 组件属性 名称展示名称默认值允许值是否必填描述例子hostnameHostname“”无是MySQL…

重点问题提问

mysql主从复制原理 slave每隔一段时间监听master&#xff0c;当master数据发生改变&#xff0c;master将数据写进二进制日志&#xff0c;slave开启一个io线程请求二进制日志&#xff0c;master在每个io线程上开启dump线程&#xff0c;将二进制日志传给slave&#xff0c;slave接…

JS 监听网络状态

我们在开发过程中会遇到监听用户网络状态的需求&#xff0c;通过JS可以获取当前的网络状态&#xff0c;包括下载速度、网络延迟、网络在线状态、网络类型等信息 具体获取如下&#xff1a; let info navigator.connection console.log(info)可以看到&#xff0c;包含几个信息…

《系统架构设计师教程(第2版)》第4章-信息安全技术基础知识-03-访问控制及数字签名技术

文章目录 1. 访问控制技术1.1 基本模型1)访问控制模型访问控制的内容1.2 实现技术1)访问控制矩阵2)访问控制表3)能力表4)授权关系表2. 数字签名2.1 作用2.2 数字签名的条件2.2 对称密钥签名2.3 公开密钥签名1. 访问控制技术 1.1 基本模

Deployment 控制器

一、概述 Deployment是ReplicaSet的高级别抽象&#xff0c;ReplicaSet控制器有的功能Deployment全部具备&#xff0c;ReplicaSet没有的Deployment也具备比如&#xff0c;它提供了滚动升级和回滚的功能。Deployment是控制多个ReplicaSet&#xff0c;从而可以实现无缝升级和回滚。…

element plus el-form双列布局及拓展任意布局

1 场景 一般表单我们直接默认布局&#xff0c;也就是单列布局&#xff0c;突然有个人员信息表单&#xff0c;需要双列布局的需求&#xff0c;简单实现并拓展下 2 思路 直接无脑divflex布局实现 3 代码 <template><el-form ref"formRef" :model"fo…

Blazor 错误笔记

1. 运行时问题 Microsoft.NETCore.App.Runtime.Mono.browser-wasm Microsoft.NETCore.App.Runtime.Mono.browser-wasm 是一个 .NET Core 运行时的包&#xff0c;用于在浏览器中运行 .NET Core 应用程序。它是针对 WebAssembly 架构的 .NET Core 运行时&#xff0c;可以在浏览…

Java中CompletableFuture 异步编排的基本使用

一、前言 在复杂业务场景中&#xff0c;有些数据需要远程调用&#xff0c;导致查询时间缓慢&#xff0c;影响以下代码逻辑运行&#xff0c;并且这些浪费时间的逻辑与以后的请求并没有关系&#xff0c;这样会大大增加服务的时间。 假如商品详情页的每个查询&#xff0c;需要如下…

C //练习 5-2 模仿函数getint的实现方法,编写一个读取浮点数的函数getfloat。getfloat函数的返回值应该是什么类型?

C程序设计语言 &#xff08;第二版&#xff09; 练习 5-2 练习 5-2 模仿函数getint的实现方法&#xff0c;编写一个读取浮点数的函数getfloat。getfloat函数的返回值应该是什么类型&#xff1f; 注意&#xff1a;代码在win32控制台运行&#xff0c;在不同的IDE环境下&#xf…

书生·浦语第三次作业

我最近在参加书生浦语大模型实战营&#xff0c;这是第三次作业打卡&#xff01; 如果你也想两周玩转大模型微调&#xff0c;部署与测评全链路。报名链接&#xff1a;invite 书生浦语大模型实战营报名 邀请码可以填026014 一、基础作业&#xff1a;复现课程知识库助手搭建过程…

LC474. 一和零

代码随想录 class Solution {public int findMaxForm(String[] strs, int m, int n) {int [][] dp new int [m1][n1];int oneNum,zeroNum;for(String str : strs){oneNum 0 ;zeroNum 0;for(char ch : str.toCharArray()){if(ch 0){zeroNum ;}else{oneNum ;}}for(int i m …

WEB之HTML练习

第一题&#xff1a;用户注册界面 HTML代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…

Java解决删除子串后的字符串最小长度

Java解决删除子串后的字符串最小长度 01 题目 给你一个仅由 大写 英文字符组成的字符串 s 。 你可以对此字符串执行一些操作&#xff0c;在每一步操作中&#xff0c;你可以从 s 中删除 任一个 "AB" 或 "CD" 子字符串。 通过执行操作&#xff0c;删除所…

【Python】使用tkinter设计开发Windows桌面程序记事本(2)

上一篇&#xff1a;【Python】使用tkinter设计开发Windows桌面程序记事本&#xff08;1&#xff09;-CSDN博客 下一篇&#xff1a; 作者发炎 此代码模块是继承上一篇文章的代码模块的基础上开始设计开发的。 如果不知道怎么新建"记事本项目"文件夹&#xff0c;请参…

第二百五十八回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"模拟对话窗口的页面"相关的内容&#xff0c;本章回中将介绍如何创建一个可以输入内容的对话框.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念…

Rust 工作空间

Rust 第23节 工作空间 工作空间 当一个项目需要多个crate时&#xff0c;就会用到工作空间 先在空白目录下创建一个 Cargo.toml 这个Cargo.toml 就是对工作空间进行管理 写上属性 [workspace]members ["adders" ]比如一个二进制crate 写完之后在命令行创建它 同…

C++ 多态以及多态的原理

文章目录 多态的概念多态的构成条件虚函数的重写虚函数重写的两个例外 重载、重写(覆盖)、重定义(隐藏)对比C11 final 和 override关键字抽象类接口继承和普通继承多态的原理虚函数表多态的原理 单继承和多继承关系的虚函数表单继承中的虚函数表多继承中的虚函数表 多态的概念 …

Linux安装nginx并设置为开机自启动

1.更新gcc安装包 yum install -y gcc pcre-devel zlib-devel2.下载文件并解压 命令如下 wget https://nginx.org/download/nginx-1.18.0.tar.gz //解压nginx tar -zxvf nginx-1.18.0.tar.gz //进入后进行指定安装位置 ./configure --prefix/usr/local/nginx //安装 make &…

面试宝典之spring框架常见面试题

F1、类的反射机制有啥用&#xff1f; &#xff08;1&#xff09;增加程序的灵活性&#xff0c;可扩展性&#xff0c;动态创建对象。 &#xff08;2&#xff09;框架必备&#xff0c;任何框架的封装都要用反射。&#xff08;框架的灵魂&#xff09; F2、获取Class对象的三种方…

boost graph计算最短路径程序异常退出问题解决

之前使用的boost 1.55版本&#xff0c;升级使用1.73版本后&#xff0c;在调用dijkstra_shortest_paths时会出现弹窗 abort()has been called 点击调试&#xff0c;看调用栈信息&#xff0c;发现计算的距离值为负数。 刚开始时&#xff0c;距离初始值为numeric_limits<long&g…