美文网首页
Web Woker 学习笔记

Web Woker 学习笔记

作者: 回调的幸福时光 | 来源:发表于2019-03-28 18:51 被阅读0次

前言

去年在某家公司面试时,最后环节CTO问关于 web worker 的问题,直接坦白工作中没用过,不怎么了解,然后被点评为技术能力不错,但是没有进行过系统性学习,有待提高。好吧,那就从哪跌倒从哪爬起来,今年看了很多基础的东西,但是看完之后很快就忘了,所以在此记录下来,以备复习。

一、what

到底啥是 web worker, 可以简单的理解成,HTML5规范中提供了一种API,通过这个 API 可以在主线程之外生成其他线程,并且其他线程在后台执行,不会影响主线程的运行。

二、how

2.1 基础用法

先来一个最简单的 hello world 。
注意:建议使用 http-server 启动一个静态服务器,因为 Worker() 无法加载本地文件(file:///xxxxx)。

index.js

// 创建 worker 线程
const worker = new Worker('worker-1.js');
// 向 worker 线程发送消息
worker.postMessage('hello world');

// 接收 worker 线程发送过来的消息
worker.onmessage = function (e) {
  console.log(e.data);
  // 关闭 worker 线程
  worker.terminate();
}

worker-1.js

// 接收主线程发送过来的消息
self.addEventListener('message', function (e) {
  // 向主线程发送消息
  self.postMessage('I received ' + e.data);
})

运行结果:

demo.png
2.2 主线程

这里要特别说明,这里讲的主线程是指浏览器`的 js 引擎线程。

JavaScript 的宿主环境浏览器是多进程的,chrome 浏览器的一个tab相当于一个渲染进程,而一个进程中包括多个线程。

示意图.png

详细请阅读文章 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

2.3 worker 线程

主线程通过 Worker() 创建了 worker 线程,注意:js 仍然是单线程的,这个 worker 线程实际上是浏览器创建的,只是可以被 js主线程操作。

const myWorker = new Worker(aURL, options);
aURL代表一个脚本文件的路径,该脚本就是 worker 线程要执行的任务。

2.4 worker 线程的全局对象(上下文)

在 worker 线程中,它的全局对象就是自身,即 this 指向的是 worker 线程自身。
这里需要注意的是,self 也指向的是 worker 线程自身

总结:使用worker线程属性或方法的 3 种方法

  • this.Fn()
  • self.Fn()
  • Fn()
2.5 数据通信

主线程向子线程发送消息
worker.postMessage()

子线程接收主线程发送的消息

// 第一种方法
addEventListener('message', function (e) {
}, false);
// 第二种方法
onmessage = function(e) {}

子线程向主线程发送消息
postMessage()

主线程接收主线程发送的消息

// 第一种方法
worker.addEventListener('message', function (e) {
}, false);
// 第二种方法
worker.onmessage = function(e) {}
2.6 数据通信的内容

主线程和 worker 线程之前的通信是拷贝关系,即是传值,而不是传址。worker 线程对通信内容的修改,不会影响到主线程,即需要将修改后的数据发送给主线程才行。

浏览器内部运行机制:先将通信内容串行化,然后把串行后的字符串传送给 worker,worker 线程再将它还原。

对二进制数据的传送
二进制数据过大,拷贝时容易导致性能问题。
javaScript 允许主线程把二进制数据转移给子线程,但是为了避免多个线程同时修改数据,所以转移后,主线程失去操作数据的能力。详细阅读 Transferable Objects

// Transferable Objects 格式
worker.postMessage(arrayBuffer, [arrayBuffer]);
2.7 错误处理

监听 error 事件

worker.onerror(function (event) {
  console.log([
    'ERROR: Line ', event.lineno, ' in ', event.filename, ': ', event.message
  ].join(''));
});

// 或者
worker.addEventListener('error', function (event) {
  // ...
});

worker线程内同上述方法。

2.8 关闭worker

主线程关闭 worker 线程

worker.terminate();

子线程关闭自身

self.close()
2.9 worker 加载脚本

worker 线程中可以通过 importScripts() 加载其他脚本。

importScripts('script1.js', 'script2.js');
2.10 worker 线程的内容和主线程在同一个页面

不感兴趣可忽略此小节,不建议此种方式使用 worker ,违反单一职责原则。

步骤:

  1. 指定<script>标签的type属性是一个浏览器不认识的值,这样浏览器就不会解析运行这段脚本。
  2. 通过 id 获取元素内容
  3. 将脚本内容转换成 blob 格式
  4. 通过 window.URL.createObjectURL(blob) 生成 url

三、why

3.1 注意事项
  1. 同源限制
    分配给 worker 线程运行的脚本,必须与主线程的脚本文件同源。
  2. DOM 限制
    worker 线程无法使用 windowdocumentparent 对象,可以使用 locationnavigator 对象。
  3. 脚本限制
    worker 线程不能执行 alert()confirm() 方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
  4. 文件限制
    worker 线程无法读取本地文件,即不能打开本机的文件系统 (file://) , 它所加载的文件必须来源于网络。
3.2 worker 的种类
  • Dedicated Workers
    专用:只能在一个script中使用
  • Shared Workers
    共享:可被不同的窗体的多个脚本运行
3.3 应用场景
  • 复杂的数学计算
  • 流媒体、图像处理

为什么web worker可以在前端开多线程,解决单线程卡死页面的问题,但是没有得到广泛使用?

参考

阮一峰 javascript教程
mdn 使用web worker

相关文章

  • Web Woker 学习笔记

    前言 去年在某家公司面试时,最后环节CTO问关于 web worker 的问题,直接坦白工作中没用过,不怎么了解,...

  • web woker

    Web Worker是 运行在后台的javascript,也就是说worker其实就是就一个js文件对象,work...

  • 2月17笔记

    第4天web学习笔记,已标明今天的笔记 有道云笔记

  • HTML基础学习笔记

    原 Blog 链接:HTML基础学习笔记 自学 html 基础笔记 Web 前端简单介绍 web 前端包含: pc...

  • 2月23笔记

    第十天web前端学习笔记 有道云笔记

  • 2月21笔记

    第八天web前端学习笔记 有道云笔记

  • 2月20笔记

    第七天web前端学习笔记 有道云笔记

  • 2月16笔记

    第三天web学习笔记,已标明今天的笔记。 有道云笔记

  • JS基础知识储备(Web Woker)

    一、概述 1、介绍 “JavaScript是单线程的”这一说法它事实上描述了JavaScript环境在浏览器内的一...

  • 2月19笔记

    第6天web前端学习 有道云笔记

网友评论

      本文标题:Web Woker 学习笔记

      本文链接:https://www.haomeiwen.com/subject/imxtbqtx.html