HTML5 新特性: Web Worker 的创建与使用(webpack + TS 环境)
HTML5 新特性: Web Worker 的创建与使用(webpack + TS 环境)
文章目录
- HTML5 新特性: Web Worker 的创建与使用(webpack + TS 环境)
- 前言
- 正文
- 1. 基础使用
- 1.1 Worker 定义
- 1.2 Worker 使用
- 2. worker-loader
- 2.1 webpack 配置
- 2.2 Worker 定义
- 2.3 Worker 使用
- 2.4 TS 环境下的配置
- 3. 实践示例:计时器
- 3.1 Worker 定义
- 3.2 Worker 使用
- 结语
- 其他资源
- 参考连接
- 完整代码示例
前言
我们都知道 JS 一直都是单线程的语言,并透过事件循环来提供异步操作的方法避免堵塞。
本篇来介绍一个 HTML5 新出的特性 Web Worker,它能够真正的为 JS 带来多线程的特性的一套规范,后续还有更多的妙用。本篇主要介绍基础的使用方式,以及在 TS 环境下的一些配置问题。
本篇不会对 Worker 的一些定义做过多的描述,主要偏重在实践并写到真实项目里头,相关的概念还是先参考一些博客会好一些
正文
1. 基础使用
首先第一版我们先搞最基础的版本,也就是直接调用浏览器最原始的 API 的使用方式
const worker = new Worker('sample.js')
实际上他会以同源的方式请求一个 js 文件,并加载作为 Worker 来执行
1.1 Worker 定义
接下来我们要定义一个 Worker 线程内要执行的脚本
/src/workers/test1.worker.js
const PREFIX_WORKER1 = '[Worker1]';self.onmessage = (event) => {const msg = event.data;console.log(`${PREFIX_WORKER1} receive msg in worker: ${msg}`);const greeting = `${msg} from test1.worker.js`;postMessage(greeting);
};
1.2 Worker 使用
下面我们看看项目内的用法
/src/layouts/Test1.tsx
const Test1 = () => {const createWorker = () => {const worker = new Worker('workers/test1.worker.js');worker.onmessage = (event) => {const msg = event.data;console.log(`${PREFIX_TEST1} worker.onmessage: ${msg}`);worker.terminate();console.log(`${PREFIX_TEST1} worker finished`);};const msg = 'Hello World';console.log(`${PREFIX_TEST1} worker.postMessage: ${msg}`);worker.postMessage('Hello World');};return (<div><h2>Test1 - Basic Worker</h2><button onClick={createWorker}>createWorker</button></div>);
};
本质上就是 1 个创建和 3 个函数的操作
- 创建 Worker
const worker = new Worker('workers/test1.worker.js');
- 发送消息
worker.postMessage('Hello World');
- 监听消息
worker.onmessage = (event) => {/* ... */}
- 终止 Worker
worker.terminate();
实现效果如下
2. worker-loader
第二种场景我们还可以在 webpack 中引入 Worker 的特性,甚至用起来比原生的更优雅
2.1 webpack 配置
首先是 webpack.config.js
配置要加上
module.exports = {// ...module: {rules: [{test: /\.worker\.(js|jsx|ts|tsx)$/,exclude: /node_modules/,use: ['worker-loader', 'ts-loader'],},]},// ...
}
2.2 Worker 定义
接下来我们在定义一个新的 Worker
/src/workers/test2.worker.ts
const PREFIX_WORKER2 = '[Worker2]';self.onmessage = (event) => {const msg = event.data;console.log(`${PREFIX_WORKER2} receive msg in worker: ${msg}`);const greeting = `${msg} from test2.worker.ts`;postMessage(greeting);
};
2.3 Worker 使用
然后我们就可以像引入一个模块一样引入一个 Worker 脚本
/src/layouts/Test2.tsx
import React from 'react';import { PREFIX_TEST2 } from '@utils/prefixs';
import Worker from '@workers/test2.worker.ts';const Test2 = () => {const createWorker = () => {const worker = new Worker();worker.onmessage = (event) => {const msg = event.data;console.log(`${PREFIX_TEST2} worker.onmessage: ${msg}`);worker.terminate();console.log(`${PREFIX_TEST2} worker finished`);};const msg = 'Hello World';console.log(`${PREFIX_TEST2} worker.postMessage: ${msg}`);worker.postMessage('Hello World');};return (<div><h2>Test2 - Worker Loader</h2><button onClick={createWorker}>createWorker</button></div>);
};export default Test2;
与第一次的差别在于
import Worker from '@workers/test2.worker.ts';const worker = new Worker();
也就是说接下来 webpack 可以将 Worker 用的脚本一并处理打包起来,而不需要我们额外再去管理 worker 的部署
2.4 TS 环境下的配置
然而上述的写法 TS 会给出一大堆报错,这时候需要补上一些配置
tsconfig.json
{"compilerOptions": {"lib": ["WebWorker", "ScriptHost", "DOM"],"allowJs": false,}
}
除此之外,默认的 Worker 构造函数是需要传入一个脚本路径名的,但是在 webpack 下我们直接 import 然后就使用无参数构造函数了,所以我们需要额外建立一个类型声明
/src/types/worker.d.ts
declare module '*.worker.ts' {class WebpackWorker extends Worker {constructor();}export default WebpackWorker;
}
最终效果如下
3. 实践示例:计时器
最后我们摆上一个用 Web Worker 做的时钟范例
3.1 Worker 定义
/src/workers/test3.worker.ts
type MessageType = 'RESET' | 'SKIP';let count = 0;
let skipOnce = false;self.onmessage = (e: MessageEvent<{ type: MessageType }>) => {const { type } = e.data;switch (type) {case 'RESET':count = 0;break;case 'SKIP':skipOnce = true;break;}
};const SEC = 1000;
setInterval(() => {if (skipOnce) {skipOnce = false;} else {count++;}self.postMessage({ currentTime: new Date(), count });
}, SEC);
3.2 Worker 使用
/src/layouts/Test3.tsx
import React, { useEffect, useRef, useState } from 'react';import Worker from '@workers/test3.worker.ts';const useWorker = () => {const [currentTime, setCurrentTime] = useState(new Date());const [count, setCount] = useState(0);const workerRef = useRef(null);useEffect(() => {const worker = new Worker();worker.onmessage = (e) => {const { currentTime, count } = e.data;setCurrentTime(currentTime);setCount(count);};workerRef.current = worker;}, []);const reset = () => {workerRef.current?.postMessage({ type: 'RESET' });setCount(0);console.log(workerRef.current);};const skip = () => {workerRef.current?.postMessage({ type: 'SKIP' });console.log(workerRef.current);};const terminate = () => {workerRef.current?.terminate();console.log(workerRef.current);};return [{ currentTime, count },{ reset, skip, terminate },];
};const Test3 = () => {const [{ currentTime, count }, { reset, skip, terminate }] = useWorker();return (<div><h2>Test3 - Timer by Worker</h2><h3>currentTime: {currentTime.toString()}</h3><h3>count: {count}</h3><button onClick={reset}>reset</button><button onClick={skip}>skip</button><button onClick={terminate}>terminate</button></div>);
};export default Test3;
最终效果
结语
Web Worker 的最大好处就是在于他真正的创建一个独立于 JS 主线程的新线程,能真正实现并行运行。
其他资源
参考连接
Title | Link |
---|---|
Web Worker 使用教程 - 阮一峰 | https://www.ruanyifeng.com/blog/2018/07/web-worker.html |
worker-loader | https://cloud.tencent.com/developer/section/1477547 |
The import path cannot end with a ‘.ts‘ extension | https://blog.csdn.net/peade/article/details/117534994 |
Typescript error “Cannot write file xxx because it would overwrite input file | https://blog.csdn.net/weixin_43459866/article/details/116356968 |
完整代码示例
https://github.com/superfreeeee/Blog-code/tree/main/front_end/html/html5_web_worker
HTML5 新特性: Web Worker 的创建与使用(webpack + TS 环境)相关推荐
- js考试题 html5新特性,Web前端初级面试题总结
Web前端初级面试题总结 发布时间:2018-11-02 11:17, 浏览次数:549 , 标签: Web Web篇: 1.常见的浏览器内核有哪些? IE:Trident内核 ...
- 前端之H5新特性Web Worker
Web Worker 使用步骤 MDN 使用步骤 1.检测浏览器是否支持worker if (window.Worker) {// ... } 2.写一个Worker要运行的JS文件(包含回传函数 - ...
- 【阿里云大学课程】前端必知——HTML5新特性完整视频教程(音频、视频、画布、web存储、动画……)...
HTML5是HTML最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定,其设计目的是为了在移动设备上支持多媒体. 本课程中,你将学习到下列这些HTML5新特性(点击下列课时立即学习): ...
- Web全栈~03.HTML5新特性
Web基本笔记~03.HTML5新特性 上一期 HTML5 新增 type 类型 email 定义用于 e-mail 地址的字段(当提交表单时会自动对 email 字段的值进行验证) E-mail: ...
- HTML5新特性知识点总结
一.HTML5特性 1.HTML5 新元素 HTML5提供了新的元素来创建更好的页面结构: <canvas> 新元素 标签 描述 <canvas> 标签定义图形,比如图表和其他 ...
- Html5新特性总览
Html5新特性总览 1.HTML5 新元素 标签 描述 < article> 定义页面独立的内容区域. < aside> 定义页面的侧边栏内容. < bdi> 定 ...
- html5新特性与用法大全了解一下
有好多小伙伴私聊我问我html5新特性 和用法,下面我给大家具体介绍一下html5都新加了哪些新特性,下面我给大家总结一下. 1)新的语义标签 footer header 等等 2)增强型表单 表单2 ...
- HTML5新特性归纳和同类比较
第一章 HTML5定义 什么是 HTML5? HTML5 是下一代HTML标准. HTML , HTML 4.01的上一个版本诞生于1999年.自从那以后,Web世界已经经历了巨变. HTML5 仍处 ...
- HTML5新特性总结大全
一.HTML5概念: 1.什么是HTML5: (1)HTML5 将成为 HTML.XHTML 以及 HTML DOM 的新标准: (2)HTML5 仍处于完善之中.然而,大部分现代浏览器已经具备了某些 ...
- HTML基础(一)--HTML5新特性和语义化
一.语义化概念 HTML5的语义化指的是合理正确的使用语义化标签来创建页面标签,正确的标签做正确的事,有利于SEO 二.语义化标签 header .nav.main(文档的主体).arcticle.s ...
最新文章
- 如何使用 Arthas 定位 Spring Boot 接口超时 ?
- R语言使用magick包的image_animate函数和image_morph函数创建一个由n个图像组成的序列,逐渐将一个图像转换成另一个图像(sequence of image morph by)
- 选 Offer 的 5 个维度
- Java高并发编程:Callable、Future和FutureTask
- 【64QAM同步】基于FPGA/MATLAB的64QAM同步系统的实现
- python3多进程写时拷贝_Python实现多进程的详解(附示例)
- Some cloud foundry deployment screenshot
- 行为设计模式:中介者
- 华为P40pro 手机云台_2020年目前拍照最好的手机推荐!华为P40 Pro!DXO全球榜首
- 用elemet-ui组件实现弹窗里的树形结构和拖拽功能
- C++开源库详细介绍
- yahoo pipes的使用
- 微软职位内部推荐-Software Development Engineering II
- Amos实操教程|调节效应检验
- 后直播时代的技术弄潮儿——TRTC
- FFmpeg+SDL纯视频播放器
- php 如何生成noncestr,如何创建和使用nonce
- LeetCode 287---Find the Duplicate Number
- CopyTranslator——一个PDF文本翻译神器
- 翔谈设计模式——观察者模式
热门文章
- spotlight搜索失效_如何在iPhone和iPad上自定义Spotlight搜索
- 第六十一期:中国农民花3000块,发明史上最牛输入法!曾火遍中国20年
- 在python中使用autoit_在Python中调用AutoIt函数
- 百度网盘等相关百度产品账号不存在问题
- 微软黑客马拉松@您,低代码风云再赛
- 解决报错 See config.log for more details 的问题
- Redis的复制(Master/Slaver)
- 给人工智能初学者看的5本入门书 | 附下载链接
- FPGA状态机跑飞 的解决办法
- 关于Android Bluetooth(安卓蓝牙)在车载产品中的使用变化