翼度科技»论坛 编程开发 html5 查看内容

JavaScript如何解决单线程缺陷——webWorker

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
解决JavaScript单线程问题——webWorkers

参考文档 使用 Web Workers - Web API 接口参考 | MDN (mozilla.org)
MDN的介绍为:
Web Worker 为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。此外,它们可以使用 XMLHttpRequest(尽管 responseXML 和 channel 属性总是为空)或 fetch(没有这些限制)执行 I/O。一旦创建,一个 worker 可以将消息发送到创建它的 JavaScript 代码,通过将消息发布到该代码指定的事件处理器(反之亦然)。
简单来说就是, 我们可以通过使用worker为主线程分担数据处理压力.
假如说你有一段很大的数据需要处理, 而你又不想这段程序阻碍你的其他操作,这时候就可以考虑一下webWorker.
如何使用webWorker

创建worker


  • 先创建一个worker.js文件, 该文件为线程代码文件, 文件中的代码会在后台线程中运行.
  • 在主线程中创建一个worker, 通过类似通讯的方式在主线程和worker中进行数据传递.
    1. // index.js主线程代码块
    2. // 简单创建一个worker名为myworker
    3. let myworker = new Worker("./firstworker.js") // 参数为firstworker.js文件的路径
    复制代码
主线程和worker之间进行通讯


  • 主线程发送数据给worker: 在主线程中通过 worker.prototype.postMessage() 进行通信
    1. // index.js主线程代码块
    2. // ... 创建完worker
    3. console.log("主线程我说句话先,接下来你要替我干活了.");
    4. // 简单向worker中发送一个数组[1, 2, 3]
    5. myworker.postMessage([1, 2, 3]);
    复制代码
  • worker接收来自主线程的数据: 在myworker.js中接收数据
    1. // firstworker.js代码块
    2. // 接收来自主线程的数据,数组[1, 2, 3]
    3. onmessage = function recive(msg) {
    4.     // 接收到的是一个MessageEvent对象, 我们可以获取data属性
    5.     console.log(msg.data); // 输出[1, 2, 3]
    6. };
    复制代码
    我们也可以使用更简洁的方式
    1. // firstworker.js代码块
    2. // 使用解构和匿名箭头函数
    3. onmessage = ({ data }) => {
    4.   console.log(data); // 输出[1, 2, 3]
    5. };
    复制代码
  • worker发送数据给主线程: 通过 postMessage() 发送数据给主线程 index.js
    接收到数组[1, 2, 3]之后, 我们可以简单的对数组进行一个逆序操作, 再把结果返回主线程
    1. // firstworker.js代码块
    2. onmessage = ({ data }) => {
    3.     // 主线程发来的数据
    4.     console.log("主线程发来的数据:", data);
    5.     // 赋值一个新变量newdata
    6.     let newdata = data;
    7.     // 对新变量操作(数组逆序)
    8.     newdata.sort((a, b) => {
    9.         return b - a;
    10.     });
    11.     console.log("worker后台线程处理完成的数据newdata:", newdata);
    12.     // 处理完的结果递交给主线程
    13.     postMessage(newdata);
    14. };
    复制代码
  • 主线程接收worker讯息: 通过 addEventListener() 对worker的动作进行监听
    1. // index.js主线程代码块
    2. // 主线程通过 监听 实例的message事件获取worker的数据
    3. // 接收myworker处理之后的结果
    4. myworker.addEventListener("message", ({ data }) => {
    5.     console.log("接收到来自worker处理完的数据:", data);
    6. });
    复制代码
关闭线程

worker.terminate()可以帮助我们在主线程中随意关闭线程, 即为从主线程中立刻终止一个运行中的 worker
  1. // index.js主线程代码块
  2. // 3s后关闭线程
  3. setTimeout(() => {
  4.     console.log("关闭myworker,你别说话了")
  5.     myWorker.terminate();
  6. }, 3000);
  7. // firstworker.js代码块
  8. setTimeout(() => {
  9.     console.log("4秒时让我说句话")
  10. }, 4000);
复制代码
worker监听

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

  • message
  • error
  • messageError:
注意事项


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

来源:https://www.cnblogs.com/waterrec/p/17467272.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具