代码中计算太多经常阻塞?试试它吧 - Web Worker

简介: Worker 在国内虽然一般场景下使用不多,可能没有什么存在感,但是其实是一项挺久远的技术了,只是由于一般情况下没什么必要性,属于锦上添花形 feature,很少会使用,不过在一些特殊场景下可以极大提高开发和用户体验。比如一些大型计算、数据加密等,还有诸如使用 OffscreenCanvas 来进行图片处理等。

网络异常,图片无法展示
|

什么是 Worker

Worker 是浏览器提供的一种可以创建独立后台线程运行代码的方式。

Worker 在国内虽然一般场景下使用不多,可能没有什么存在感,但是其实是一项挺久远的技术了,只是由于一般情况下没什么必要性,属于锦上添花形 feature,很少会使用,不过在一些特殊场景下可以极大提高开发和用户体验。比如一些大型计算、数据加密等,还有诸如使用 OffscreenCanvas 来进行图片处理等。

Worker 主要包括以下几种:

  1. 常见的 Web Worker,几乎所有浏览器都很早就支持,
  2. Shared Worker,一种特殊的 Web Worker,可以被多个窗口共享
  3. Service Worker,主要使用在 PWA 应用中,可以帮助构建离线应用
  4. Worklet,现在还属于实验性质,算是一种轻量级的 Web Worker,但是他可以做到访问一些渲染相关的 API

本篇先聊一聊最常用的 Web Worker

Web Worker 会在浏览器中创建一个独立的后台线程,然后执行传入的脚本,和主线程的通信主要是通过 postMessageonmessage 来实现。不过 Web Worker 中只能使用一部分的 API,如 WebSocketDate 等,而像一些 DOM 相关的 API 是无法使用的,原因很好理解,主要是为了避免线程冲突,一旦 Web Worker 线程可以操作 DOM,那诸如各种时间锁就要出现了。

创建

要创建一个 Web Worker,我们只需要建立一个独立的 worker.js 文件,然后通过 new Worker('./worker.js') 来引用即可:

const worker = new Worker('./worker.js');
复制代码

当然也可以通过 createObjectURL 来创建虚拟 url 来创建,如之前说过的 use-worker 便是使用这种方式。

通信

而通信则通过 postMessage 来完成,如主线程需要发送消息给 worker

worker.postMessage('Hello, my worker');
worker.addEventListener('message', e => {
    console.log(e);
});
复制代码

worker 文件的主体则是一个 onmessage 函数:

worker.js

onmessage = function (e) {
    console.log('Message received:', e);
    postMessage('Yes, my lord');
};
复制代码

当接收到主线程消息后,则会进入 onmessage 函数,而 workerpostMessage 不需要主体,直接调用即为发送给创建它的主线程。

销毁

要销毁一个 worker,只需要调用 terminate 方法即可:

worker.terminate();
复制代码

调用后 worker 会立刻终止并关闭,类似于操作系统中 kill 一段进程。当然 worker 也可以直接调用 close 来自行关闭:

close();
复制代码

错误处理

worker 的事件除了 message 外还包括 errormessageerrorrejectionhandledunhandledrejection,可监听对应的事件来处理对应的错误。

  • error:普通执行错误
  • messageerrorpostMessage 数据错误,一般出现在传递的数据类型不合法的情况
  • rejectionhandled:所有的 Promise reject 时触发
  • unhandledrejectionPromise reject 未处理时触发

引入外部脚本

Worker 中还可以通过 importScripts 来导入外部脚本:

importScripts('lodash.js');
复制代码

要注意 importScripts 为同步请求,会阻塞 worker 线程。如果在外部脚本中有导出,可通过挂载在全局变量中,要注意在 worker 中,全局变量需通过 self 引用,而非 window,上述的 close 一样可以通过 self 来进行调用。

importScripts('lodash.js');
_.each([1, 2, 3], n => {
    console.log(n);
});
复制代码

上述便是关于 Web Worker 的内容,下面会聊一聊其它几种 worker

相关文章
|
9月前
vite环境引入web worker方法
在 vite 环境中使用 web worker 时,如果遇到生产环境中 worker.js 文件的 MIME 类型被识别为 text/html,导致报错无法运行的情况时,可以参考以下两种方法,原理都是避免编译时产出单独的 worker.js 文件。方法一worker文件不需要包装,引入时后缀增加 ?worker&inline,使用时直接 new ImportedWorker();self.
487 0
|
10月前
|
Java
【Java Web】设计网页计算一元二次方程的解
【Java Web】设计网页计算一元二次方程的解
165 0
|
1天前
|
前端开发 Java Spring
Java Web ——MVC基础框架讲解及代码演示(下)
Java Web ——MVC基础框架讲解及代码演示
8 1
|
1天前
|
设计模式 前端开发 网络协议
Java Web ——MVC基础框架讲解及代码演示(上)
Java Web ——MVC基础框架讲解及代码演示
6 0
|
1天前
|
前端开发 JavaScript 开发者
前端技术栈:探索现代Web开发的核心要素与代码实践
前端技术栈:探索现代Web开发的核心要素与代码实践
21 1
|
1天前
|
JavaScript 安全 数据处理
Web Worker:让网页飞起来的幕后英雄(下)
Web Worker:让网页飞起来的幕后英雄(下)
Web Worker:让网页飞起来的幕后英雄(下)
|
1天前
|
缓存 编解码 数据处理
Web Worker:让网页飞起来的幕后英雄(上)
Web Worker:让网页飞起来的幕后英雄(上)
Web Worker:让网页飞起来的幕后英雄(上)
|
6月前
|
数据采集 JavaScript 前端开发
超越React,JS代码体积减少90%!它为何是2023年最好的Web框架?
超越React,JS代码体积减少90%!它为何是2023年最好的Web框架?
|
9月前
|
Web App开发 移动开发 JavaScript
web worker详解
web worker详解
133 0
|
9月前
|
缓存 弹性计算 分布式计算
阿里云适合建网、web应用、数据分析和计算、数据库系统的云服务器价格参考
阿里云服务器新客专享,新用户完成账号实名认证,享受优惠价格购买计算型、通用型、内存型云服务器爆款配置特价优惠,限1-2台,这些云服务器主要适合搭建网站、web应用、数据分析和计算、数据库系统等中小类型和规模的企业级应用。
348 1
阿里云适合建网、web应用、数据分析和计算、数据库系统的云服务器价格参考