解决JavaScript单线程问题——webWorkers

参考文档 使用 Web Workers - Web API 接口参考 | MDN (mozilla.org)

MDN的介绍为:

Web Worker 为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。此外,它们可以使用 XMLHttpRequest(尽管 responseXMLchannel 属性总是为空)或 fetch(没有这些限制)执行 I/O。一旦创建,一个 worker 可以将消息发送到创建它的 JavaScript 代码,通过将消息发布到该代码指定的事件处理器(反之亦然)。

简单来说就是, 我们可以通过使用worker为主线程分担数据处理压力.

假如说你有一段很大的数据需要处理, 而你又不想这段程序阻碍你的其他操作,这时候就可以考虑一下webWorker.

如何使用webWorker

创建worker

  1. 先创建一个worker.js文件, 该文件为线程代码文件, 文件中的代码会在后台线程中运行.

  2. 在主线程中创建一个worker, 通过类似通讯的方式在主线程和worker中进行数据传递.

    // index.js主线程代码块
    // 简单创建一个worker名为myworker
    let myworker = new Worker("./firstworker.js") // 参数为firstworker.js文件的路径

主线程和worker之间进行通讯

  1. 主线程发送数据给worker: 在主线程中通过 worker.prototype.postMessage() 进行通信

    // index.js主线程代码块
    // ... 创建完worker console.log("主线程我说句话先,接下来你要替我干活了.");
    // 简单向worker中发送一个数组[1, 2, 3]
    myworker.postMessage([1, 2, 3]);
  2. worker接收来自主线程的数据: 在myworker.js中接收数据

    // firstworker.js代码块
    // 接收来自主线程的数据,数组[1, 2, 3]
    onmessage = function recive(msg) {
    // 接收到的是一个MessageEvent对象, 我们可以获取data属性
    console.log(msg.data); // 输出[1, 2, 3]
    };

    我们也可以使用更简洁的方式

    // firstworker.js代码块
    // 使用解构和匿名箭头函数
    onmessage = ({ data }) => {
    console.log(data); // 输出[1, 2, 3]
    };
  3. worker发送数据给主线程: 通过 postMessage() 发送数据给主线程 index.js

    接收到数组[1, 2, 3]之后, 我们可以简单的对数组进行一个逆序操作, 再把结果返回主线程

    // firstworker.js代码块
    onmessage = ({ data }) => {
    // 主线程发来的数据
    console.log("主线程发来的数据:", data);
    // 赋值一个新变量newdata
    let newdata = data;
    // 对新变量操作(数组逆序)
    newdata.sort((a, b) => {
    return b - a;
    });
    console.log("worker后台线程处理完成的数据newdata:", newdata);
    // 处理完的结果递交给主线程
    postMessage(newdata);
    };
  4. 主线程接收worker讯息: 通过 addEventListener() 对worker的动作进行监听

    // index.js主线程代码块
    // 主线程通过 监听 实例的message事件获取worker的数据
    // 接收myworker处理之后的结果
    myworker.addEventListener("message", ({ data }) => {
    console.log("接收到来自worker处理完的数据:", data);
    });

关闭线程

worker.terminate()可以帮助我们在主线程中随意关闭线程, 即为从主线程中立刻终止一个运行中的 worker

// index.js主线程代码块
// 3s后关闭线程
setTimeout(() => {
console.log("关闭myworker,你别说话了")
myWorker.terminate();
}, 3000); // firstworker.js代码块
setTimeout(() => {
console.log("4秒时让我说句话")
}, 4000);

worker监听

主线程通过 addEventListener() 对worker动作进行监听, 动作包含三种

  • message
  • error
  • messageError:

注意事项

  1. worker是HTML5规范的API,所以你没法在node环境中使用.
  2. worker没办法对dom元素操作, 只能在主线程中, 多线程操作dom感觉就不大好.
  3. worker可以用于执行长时间运行的计算、处理大量数据、执行网络请求等任务,而不会影响用户界面的响应性能.帮助开发人员提高Web应用程序的性能和响应性能.
  4. 本文章只对worker的使用进行了简单介绍, 具体进阶用法等详细内容还得参考MDN文档(共享worker, 线程安全, 嵌入式worker等)

JavaScript如何解决单线程缺陷——webWorker的更多相关文章

  1. JavaScript之JS单线程|事件循环|事件队列|执行栈

    本博文基于知乎"JavaScript作用域问题?"一问,而引起了对JavaScript事件循环和单线程等概念与实践上的研究.深入理解. 一.概念 0.关键词:JavaScript单 ...

  2. Javascript引擎的单线程机制和setTimeout执行原理阐述

    工作中使用setTimeout解决了一个问题,于是对setTimeout的相关资料整理了下,以及对js引擎执行的原理一并整理了下,希望能给码农们一些帮助.若发现有错的地方大家及时指出,共同学习进步. ...

  3. JavaScript到底是不是单线程

    JavaScript到底是不是单线程 JavaScript引擎 在了解计时器内部运作前,我们必须清楚一点,触发和执行并不是同一概念,计时器的回调函数一定会在指定delay的时间后被触发,但并不一定立即 ...

  4. Javascript定时器(一)——单线程

    一.JavaScript 引擎是单线程的 可以从下面的代码中看到,第一个用setTimeout中的代码是死循环,由于是单线程,下面的两个定时器就没机会执行了. <script type=&quo ...

  5. JavaScript 闭包解决计数器问题

    JavaScript 闭包解决计数器问题 var add = (function () { var counter = 0; return function () {return counter += ...

  6. JavaScript引擎是单线程的

    从基础的层面来讲,理解JavaScript的定时器是如何工作的是非常重要的.计时器的执行常常和我们的直观想象不同,那是因为JavaScript引擎是单线程的.我们先来认识一下下面三个函数是如何控制计时 ...

  7. Javascript:必须知道的Javascript知识点之“单线程事件驱动”

    heiboard: Javascript:必须知道的Javascript知识点之“单线程事件驱动”

  8. 编程原理—如何用javascript代码解决一些问题

    关于编程,我最喜欢的就是解决问题.我不相信有谁天生具有解决问题的能力.这是一种通过反复锻炼而建立并维持的能力.像任何练习一样,有一套指导方针可以帮助你更有效地提高解决问题的能力.我将介绍5个最重要的软 ...

  9. JavaScript异步和单线程

    一,同步和异步的区别: 同步会阻塞代码执行,而异步不会.(比如alert是同步,setTimeout是异步) 二,前端使用异步的场景: 1,定时任务:setTimeout,setInterval 2, ...

  10. 常见JS(JavaScript)冲突解决方法

    1.一般JS冲突解决办法 a.最容易出现的就是js的命名冲突 ①.变量名冲突 变量有全局变量和局部变量当全局变量变量和局部变量名称一致时,就会js冲突,由于变量传递数值或地址不同就会产生JavaScr ...

随机推荐

  1. QGIS 导入文本数据(WKT)

    在做GIS数据处理的时候,经常会遇到原始数据是 text.csv.Excel 等格式的数据.要使用数据前提是要先转换数据. 这里是介绍用 QGIS 导入数据.打开导入方式如下(根据自己的文本类型选择不 ...

  2. 三分钟速览GPT系列原理

    其中,Transformer和BERT来自Google,GPT系列[GPT.GPT-1.GPT-2.GPT-3.ChatGPT.GPT-4]来自OpenAI. GPT Paper名为Improving ...

  3. Troubleshooting 专题 - 问正确的问题 得到正确的答案

    在很多公司中,IT.数据中心.业务系统一出故障,会有很多人被叫到作战室(就是一个为了解决该问题,而把所有相关人员集中在一起的一个会议室), 但是对于这个问题他们是否可以修复, 是否他们应该负有责任, ...

  4. kubernetes核心实战(四)--- Deployments

    6.Deployments(重点) 一个 Deployment 控制器为 Pods和 ReplicaSets提供描述性的更新方式. 描述 Deployment 中的 desired state,并且 ...

  5. 如何使用sms-activate解决短信验证码问题

    目录 前言 第一步:注册sms-activate 第二步:找到我们需要的服务 第三步:使用服务 前言 最近有许多小伙伴私信我,由于他们的工作需要让我安利一款接码工具供他们使用,于是我在调研各大接码平台 ...

  6. Redis缓冲区溢出及解决方案

    缓冲区(buffer),是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区. 一.Redis缓冲区溢出影响 在Redis ...

  7. win10启动docker报错,错误码 0xffffffff

    一.注册表修复(如果有就不用管) 在\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\AppId_Ca ...

  8. 关于Validation的方法使用

    acceptance验证 acceptance 是 Rails 中的一个验证器(validator),用于验证一个布尔类型的属性是否被接受.在表单中,通常会有一些复选框或单选按钮,用户需要勾选或选择才 ...

  9. 【观察者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    简介 观察者模式(Observer Pattern)是一种行为型模式.它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 观察者模式使用三个类S ...

  10. js 获取窗口/容器内部滚动位置

    前端 (document.getElementsByClassName("container")[0]).scrollTop -- 容器内部滚动条位置 (document.getE ...