解决JavaScript单线程问题webWorkers

更新日期: 2023-06-12阅读: 4.6k标签: 线程

webWorker介绍

MDN的介绍为:

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

简单来说就是, 我们可以通过使用worker为主线程分担数据处理压力.
假如说你有一段很大的数据需要处理, 而你又不想这段程序阻碍你的其他操作,这时候就可以考虑一下webWorker.


如何使用webWorker

创建worker

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

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

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


主线程和worker之间进行通讯

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

// index.js主线程代码块
// ... 创建完worker

console.log("主线程我说句话先,接下来你要替我干活了.");
// 简单向worker中发送一个数组[1, 2, 3]
myworker.postMessage([1, 2, 3]);

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]
};

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);
};

主线程接收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:


注意事项

worker是html5规范的api,所以你没法在node环境中使用.

worker没办法对dom元素操作, 只能在主线程中, 多线程操作dom感觉就不大好.

worker可以用于执行长时间运行的计算、处理大量数据、执行网络请求等任务,而不会影响用户界面的响应性能.帮助开发人员提高Web应用程序的性能和响应性能.

文章只对worker的使用进行了简单介绍, 具体进阶用法等详细内容还得参考MDN文档(共享worker, 线程安全, 嵌入式worker等)

本文作者:WaterRec
本文链接:https://www.cnblogs.com/waterrec/p/17467272.html

链接: https://www.fly63.com/article/detial/12511

理解的线程、进程的关系与区别

进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。一简言之: 进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。

javascript中的伪线程,使用setTimeout模拟一个多线程

浏览器的内核是多线程的,一个浏览器一般至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。当我们要循环过百万级的数据甚至亿的时候怎么办?那就用setTimeout模拟一个多线程。

聊聊 JavaScript 与浏览器的那些事 - 引擎与线程

对 JavaScript 解释器和浏览器的线程机制理解的不是特别透彻,很容易混淆浏览器多线程机制并错误认为由于 Web Worker 的设计使得 JavaScript 拥有了多线程的能力。事后搜了不少资料进行学习,整理成此文,主要介绍浏览器的各个引擎、线程间的工作机制以及 JavaScript 单线程的一些事。

浏览器进程线程

进程是正在运行的程序的实例;线程(英语:thread)是操作系统能够进行运算调度的最小单位。可以打开任务管理器,可以看到有一个后台进程列表。这里就是查看进程的地方,而且可以看到每个进程的内存资源信息以及cpu占有率。

JavaScript多线程编程

浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,浏览器就会出现卡顿,降低了用户体验。

Node.js 多线程完全指南

很多人都想知道单线程的 Node.js 怎么能与多线程后端竞争。考虑到其所谓的单线程特性,许多大公司选择 Node 作为其后端似乎违反直觉。要想知道原因,必须理解其单线程的真正含义。

JavaScript Event Loop和微任务、宏任务

JavaScript的一大特点就是单线程, 同一时间只能做一件事情,主要和它的用途有关, JavaScript主要是控制和用户的交互以及操作DOM。注定它是单线程。 假如是多个线程, 一个移除DOM节点,一个新增DOM节点,浏览器以谁的为准呢?

如何理解JS的单线程?

JS本质是单线程的。也就是说,它并不能像JAVA语言那样,两个线程并发执行。 但我们平时看到的JS,分明是可以同时运作很多任务的,这又是怎么回事呢?

理解JS执行顺序

众所周知,JS的执行顺序是自上而下的。 严格意义上来说,javascript没有多线程的概念,所有的程序都是单线程依次执行的。 就是代码在执行过程中,另一段代码想要执行就必须等当前代码执行完成后才可以进行。

初始WebWorker

JS单线程:我们都知道JavaScript它是一个单线程的语言,同一时间只能做一件事。比如:在浏览器中,某一时刻我们在操作DOM,你们这个时刻我们就不能去运行JavaScript代码,反过来也是,当我们在运行JavaScript代码的时候

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!