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 个函数的操作

  1. 创建 Worker
const worker = new Worker('workers/test1.worker.js');
  1. 发送消息
worker.postMessage('Hello World');
  1. 监听消息
worker.onmessage = (event) => {/* ... */}
  1. 终止 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 环境)相关推荐

  1. js考试题 html5新特性,Web前端初级面试题总结

    Web前端初级面试题总结 发布时间:2018-11-02 11:17, 浏览次数:549 , 标签: Web Web篇: 1.常见的浏览器内核有哪些? IE:Trident内核            ...

  2. 前端之H5新特性Web Worker

    Web Worker 使用步骤 MDN 使用步骤 1.检测浏览器是否支持worker if (window.Worker) {// ... } 2.写一个Worker要运行的JS文件(包含回传函数 - ...

  3. 【阿里云大学课程】前端必知——HTML5新特性完整视频教程(音频、视频、画布、web存储、动画……)...

    HTML5是HTML最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定,其设计目的是为了在移动设备上支持多媒体. 本课程中,你将学习到下列这些HTML5新特性(点击下列课时立即学习): ...

  4. Web全栈~03.HTML5新特性

    Web基本笔记~03.HTML5新特性 上一期 HTML5 新增 type 类型 email 定义用于 e-mail 地址的字段(当提交表单时会自动对 email 字段的值进行验证) E-mail: ...

  5. HTML5新特性知识点总结

    一.HTML5特性 1.HTML5 新元素 HTML5提供了新的元素来创建更好的页面结构: <canvas> 新元素 标签 描述 <canvas> 标签定义图形,比如图表和其他 ...

  6. Html5新特性总览

    Html5新特性总览 1.HTML5 新元素 标签 描述 < article> 定义页面独立的内容区域. < aside> 定义页面的侧边栏内容. < bdi> 定 ...

  7. html5新特性与用法大全了解一下

    有好多小伙伴私聊我问我html5新特性 和用法,下面我给大家具体介绍一下html5都新加了哪些新特性,下面我给大家总结一下. 1)新的语义标签 footer header 等等 2)增强型表单 表单2 ...

  8. HTML5新特性归纳和同类比较

    第一章 HTML5定义 什么是 HTML5? HTML5 是下一代HTML标准. HTML , HTML 4.01的上一个版本诞生于1999年.自从那以后,Web世界已经经历了巨变. HTML5 仍处 ...

  9. HTML5新特性总结大全

    一.HTML5概念: 1.什么是HTML5: (1)HTML5 将成为 HTML.XHTML 以及 HTML DOM 的新标准: (2)HTML5 仍处于完善之中.然而,大部分现代浏览器已经具备了某些 ...

  10. HTML基础(一)--HTML5新特性和语义化

    一.语义化概念 HTML5的语义化指的是合理正确的使用语义化标签来创建页面标签,正确的标签做正确的事,有利于SEO 二.语义化标签 header .nav.main(文档的主体).arcticle.s ...

最新文章

  1. 如何使用 Arthas 定位 Spring Boot 接口超时 ?
  2. R语言使用magick包的image_animate函数和image_morph函数创建一个由n个图像组成的序列,逐渐将一个图像转换成另一个图像(sequence of image morph by)
  3. 选 Offer 的 5 个维度
  4. Java高并发编程:Callable、Future和FutureTask
  5. 【64QAM同步】基于FPGA/MATLAB的64QAM同步系统的实现
  6. python3多进程写时拷贝_Python实现多进程的详解(附示例)
  7. Some cloud foundry deployment screenshot
  8. 行为设计模式:中介者
  9. 华为P40pro 手机云台_2020年目前拍照最好的手机推荐!华为P40 Pro!DXO全球榜首
  10. 用elemet-ui组件实现弹窗里的树形结构和拖拽功能
  11. C++开源库详细介绍
  12. yahoo pipes的使用
  13. 微软职位内部推荐-Software Development Engineering II
  14. Amos实操教程|调节效应检验
  15. 后直播时代的技术弄潮儿——TRTC
  16. FFmpeg+SDL纯视频播放器
  17. php 如何生成noncestr,如何创建和使用nonce
  18. LeetCode 287---Find the Duplicate Number
  19. CopyTranslator——一个PDF文本翻译神器
  20. 翔谈设计模式——观察者模式

热门文章

  1. spotlight搜索失效_如何在iPhone和iPad上自定义Spotlight搜索
  2. 第六十一期:中国农民花3000块,发明史上最牛输入法!曾火遍中国20年
  3. 在python中使用autoit_在Python中调用AutoIt函数
  4. 百度网盘等相关百度产品账号不存在问题
  5. 微软黑客马拉松@您,低代码风云再赛
  6. 解决报错 See config.log for more details 的问题
  7. Redis的复制(Master/Slaver)
  8. 给人工智能初学者看的5本入门书 | 附下载链接
  9. FPGA状态机跑飞 的解决办法
  10. 关于Android Bluetooth(安卓蓝牙)在车载产品中的使用变化