当前位置: 首页 > article >正文

什么是Web Worker?如何使用Web Worker?

1. 什么是 Web Worker?

JavaScript 语言采用的是单线程的,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。

Web Worker 是一种在浏览器中实现多线程处理的技术,允许在后台线程中执行脚本,从而避免长时间运行的脚本阻塞用户界面。

Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。

主线程与 Worker 之间的通信内容,可以是文本,也可以是对象。

2. Web Worke主要特点

  1. 同源限制: Worker 线程必须与主线程的脚本文件同源。

  2. 通信机制:主线程和 Worker 线程之间不能直接通信,必须通过消息传递(postMessageonmessage)进行通信。消息传递是异步的,确保了线程间的隔离和安全性。

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

    😊为什么消息传递中的数据不是被共享而是被复制?
    ● 与共享内存不同,两个线程之间并没有直接访问对方内存的能力。每个线程只能访问自己的内存空间,通过消息传递的方式进行通信。
    ● 复制数据可以避免多个线程同时修改同一块内存,从而避免数据竞争和线程安全问题。

  3. 资源限制: Worker 线程不能访问 DOM,也不能使用某些全局对象(如 window),也无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

3. Web Worker的基本用法

3.1 主线程

主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程。

const worker = new Worker('work.js');

Worker()构造函数的参数是一个来自网络的脚本文件,该文件就是 Worker 线程所要执行的任务。由如果下载没有成功(比如404错误),Worker 就会默默地失败。
然后,主线程调用·worker.postMessage() 方法,向 Worker 发消息。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Worker Example</title>
</head>
<body>
    <button id="start">Start Calculation</button>
    <p id="result"></p>

    <script>
        // 主线程采用new命令,调用Worker()构造函数,创建一个新的 Worker
        const worker = new Worker('worker.js');

        document.getElementById('start').addEventListener('click', function() {
            // 向 Worker 发送数据
            const data = 10;
            worker.postMessage(data);
        });

        // 监听 Worker 发送的消息
        worker.onmessage = function(e) {
          //事件对象的data属性可以获取 Worker 发来的数据
            const result = e.data;
            document.getElementById('result').textContent = 'Result: ' + result;
        };

        // 监听 Worker 的错误
        worker.onerror = function(error) {
            console.error('Worker error:', error);
        };
    </script>
</body>
</html>

Worker 完成任务以后,主线程就可以把它关掉。

worker.terminate();

3.2 Worker 线程

Worker 线程内部需要有一个监听函数,监听message事件。

// worker.js
self.onmessage = function(e) {
    const data = e.data;
    console.log('Received data:', data);
    // 处理数据
    const result = data * 2;
    // 发送结果回主线程
    self.postMessage(result);
};

上面代码中,self代表子线程自身,即子线程的全局对象。也等同于下面写法:

self.addEventListener('message', function (e) {
    const data = e.data;
    console.log('Received data:', data);
    // 处理数据
    const result = data * 2;
    // 发送结果回主线程
    self.postMessage(result);
}, false);

关闭Worker 线程:

self.close();

Worker 加载脚本:

importScripts('script1.js');
// 同时加载多个脚本
importScripts('script1.js', 'script2.js');

4.Web Worker的API

主线程:
worker.onerror:指定 error 事件的监听函数。
worker.onmessage:指定 message 事件的监听函数,发送过来的数据在Event.data属性中。
worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
worker.postMessage():向 Worker 线程发送消息
worker.terminate():立即终止 Worker 线程。

Worker 线程:
self.name: Worker 的名字。该属性只读,由构造函数指定。
self.onmessage:指定message事件的监听函数。
self.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
self.close():关闭 Worker 线程。
self.postMessage():向产生这个 Worker 线程发送消息。
self.importScripts():加载 JS 脚本。


http://www.kler.cn/a/413450.html

相关文章:

  • (计算机网络)期末
  • [UUCTF 2022 新生赛]ez_rce
  • 斐波那契堆与二叉堆在Prim算法中的性能比较:稀疏图与稠密图的分析
  • 高级java每日一道面试题-2024年11月27日-JVM篇-JVM的永久代中会发生垃圾回收么?
  • Linux文件基础
  • Web 学习笔记 - 网络安全
  • Linux系統中修改IP地址詳細教程
  • Elasticseach黑马笔记
  • 【设计模式】【创建型模式(Creational Patterns)】之建造者模式(Builder Pattern)
  • AI助力PPT创作:从手动到智能,打造高效演示
  • 比特币libsecp256k1中safegcd算法形式化验证完成
  • Java基于SSM框架的校园综合服务小程序【附源码、文档】
  • thinkphp中对请求封装
  • matlab模糊fis文件制作
  • 《Vue零基础入门教程》第八课:模板语法
  • docker compose的安装和使用
  • el-row el-col显示失效问题修复
  • CTF之密码学(栅栏加密)
  • IntelliJ+SpringBoot项目实战(十六)--在SpringBoot中整合SpringSecurity和JWT(下A)
  • Jenkins流水线 Allure JUnit5 自动化测试
  • vue3项目搭建-4-正式启动项目,git管理
  • 如何寻找适合的HTTP代理IP资源?
  • 13 —— 开发环境调错-source map
  • 本地部署 WireGuard 无需公网 IP 实现异地组网
  • Redis中如何使用lua脚本-即redis与lua的相互调用
  • coqui-ai TTS 初步使用