代码中计算太多经常阻塞?试试它吧 - 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

相关文章
|
1月前
|
计算机视觉 Python
Flask学习笔记(六):基于Flask的摄像头-web显示代码(可直接使用)
这篇文章是关于如何使用Flask框架结合OpenCV库,通过电脑摄像头实现视频流在网页上的实时显示,并提供了单摄像头和多摄像头的实现方法。
86 2
Flask学习笔记(六):基于Flask的摄像头-web显示代码(可直接使用)
|
2月前
|
XML JSON 安全
Web安全-代码注入
Web安全-代码注入
25 6
|
3月前
|
前端开发 JavaScript 大数据
React与Web Workers:开启前端多线程时代的钥匙——深入探索计算密集型任务的优化策略与最佳实践
【8月更文挑战第31天】随着Web应用复杂性的提升,单线程JavaScript已难以胜任高计算量任务。Web Workers通过多线程编程解决了这一问题,使耗时任务独立运行而不阻塞主线程。结合React的组件化与虚拟DOM优势,可将大数据处理等任务交由Web Workers完成,确保UI流畅。最佳实践包括定义清晰接口、加强错误处理及合理评估任务特性。这一结合不仅提升了用户体验,更为前端开发带来多线程时代的全新可能。
73 1
|
3月前
|
数据库 开发者 Java
数据战争:Hibernate的乐观与悲观锁之争,谁将主宰并发控制的王座?
【8月更文挑战第31天】在软件开发中,数据一致性至关重要,尤其是在多用户并发访问环境下。Hibernate 作为 Java 社区常用的 ORM 框架,提供了乐观锁和悲观锁机制来处理并发问题。乐观锁假设数据不易冲突,通过版本号字段 (`@Version`) 实现;悲观锁则假定数据易冲突,在读取时即加锁。选择哪种锁取决于具体场景:乐观锁适合读多写少的情况,减少锁开销;悲观锁适合写操作频繁的场景,避免数据冲突。正确应用这些机制可提升应用程序的健壮性和效率。
36 0
|
3月前
|
Java UED 自然语言处理
Struts 2 国际化竟有如此神奇魔力?快来揭开多语言支持的 Web 应用神秘面纱
【8月更文挑战第31天】在全球化背景下,Web应用需适应多种语言环境。Struts 2凭借其强大的国际化(i18n)支持,简化了多语言应用开发。通过不同语言的资源文件,它能自动匹配用户语言偏好,优化用户体验并扩展用户群。下面是一个示例:创建`messages.properties`(英语)与`messages_zh_CN.properties`(中文),并在Struts 2的Action类及JSP页面中调用`getText()`方法及Struts标签展示相应语言内容。此外,在struts.xml中指定资源文件,以确保框架正确加载对应语言包。通过这些步骤,开发者可以轻松实现应用的多语言支持。
65 0
|
3月前
|
Java 开发者 JavaScript
Struts 2 开发者的秘籍:隐藏的表单标签库功能,能否成为你下个项目的大杀器?
【8月更文挑战第31天】Struts 2表单标签库是提升Web页面交互体验的神器。它提供丰富的标签,如`<s:textfield>`和`<s:select>`,简化表单元素创建与管理,支持数据验证和动态选项展示。结合示例代码,如创建文本输入框并与Action类属性绑定,显著提升开发效率和用户体验。通过自定义按钮样式等功能,Struts 2表单标签库让开发者更专注于业务逻辑实现。
47 0
|
3月前
|
iOS开发 Android开发 MacOS
从零到全能开发者:解锁Uno Platform,一键跨越多平台应用开发的神奇之旅,让你的代码飞遍Windows、iOS、Android、macOS及Web,技术小白也能秒变跨平台大神!
【8月更文挑战第31天】从零开始,踏上使用Uno Platform开发跨平台应用的旅程。只需编写一次代码,即可轻松部署到Windows、iOS、macOS、Android及Web(通过WASM)等多个平台。Uno Platform为.NET生态带来前所未有的灵活性和效率,简化跨平台开发。首先确保安装了Visual Studio或VS Code及.NET SDK,然后选择合适的项目模板创建新项目。项目结构类似传统.NET MAUI或WPF项目,包含核心NuGet包。通过简单的按钮示例,你可以快速上手并构建应用。Uno Platform让你的技术探索之旅充满无限可能。
68 0
|
3月前
|
前端开发 开发者 Apache
揭秘Apache Wicket项目结构:如何打造Web应用的钢铁长城,告别混乱代码!
【8月更文挑战第31天】Apache Wicket凭借其组件化设计深受Java Web开发者青睐。本文详细解析了Wicket项目结构,帮助你构建可维护的大型Web应用。通过示例展示了如何使用Maven管理依赖,并组织页面、组件及业务逻辑,确保代码清晰易懂。Wicket提供的页面继承、组件重用等功能进一步增强了项目的可维护性和扩展性。掌握这些技巧,能够显著提升开发效率,构建更稳定的Web应用。
103 0
|
3月前
|
人工智能 开发者 前端开发
【创新·未来】当AI遇见代码:Vaadin Copilot引领Web开发新时代,你准备好了吗?
【8月更文挑战第31天】Vaadin 是一个成熟的 Java Web 应用框架,最新版本 24.4.0 带来了多项更新,包括引入 Vaadin Copilot——一个集成 AI 的开发工具,可实现拖放组件、实时更新源代码等功能。此外,Vaadin 24.4.0 还统一了 Hilla 框架,支持 Flow 和 Hilla 视图混合应用,实现 React 组件与 Java 应用的无缝集成。未来,Vaadin 将继续提升开发者体验和应用性能,整合更多现代 Web 技术,如 Web 组件和 PWA 支持,保持其在企业级应用开发领域的领先地位。
57 0
|
3月前
|
前端开发 程序员 API
从后端到前端的无缝切换:一名C#程序员如何借助Blazor技术实现全栈开发的梦想——深入解析Blazor框架下的Web应用构建之旅,附带实战代码示例与项目配置技巧揭露
【8月更文挑战第31天】本文通过详细步骤和代码示例,介绍了如何利用 Blazor 构建全栈 Web 应用。从创建新的 Blazor WebAssembly 项目开始,逐步演示了前后端分离的服务架构设计,包括 REST API 的设置及 Blazor 组件的数据展示。通过整合前后端逻辑,C# 开发者能够在统一环境中实现高效且一致的全栈开发。Blazor 的引入不仅简化了 Web 应用开发流程,还为习惯于后端开发的程序员提供了进入前端世界的桥梁。
318 0

热门文章

最新文章