Javascript 基础夯实 —— 使用 webWorker 实现多线程(转)
原文链接:https://zhuanlan.zhihu.com/p/29219879
当我们开始学习 javascript 的时候,我们就知道 js 其实是单线程的,所以当我们在浏览器中运行某些耗时算法或者阻塞线程的代码时,浏览器就会出现卡顿的现象
然而 js 引擎却拥有多个线程,比如渲染界面线程、浏览器事件触发线程、http 请求线程、事件轮询处理线程等
如果我们能够将一部分代码放在一个新的线程中执行,比如 http 请求的方法、需要大量计算耗时较多的方法,既能够保证页面对用户及时响应,又不会阻塞页面
这在以前是不可能的,但是现在,H5 为我们提供了一个方法 —— webWorker
什么是 webWorker
webWorker 是浏览器为我们提供的一个可以再浏览器后台开启一个新的线程的 API,使得运行在浏览器中的 js 有了多线程的能力。但是这并不意味这 js 本身就支持多线程
webWorker 有两种类型,一种是只能在当前页面使用的 webworker,另一种是可以再多个页面之间共享线程的 webWorker,前者随着当前页面关闭而关闭,而后者在同域的前提下,可以被多个页面访问
webWorker 的创建与使用
// webWorker 是在主线程中通过传入一个 js 文件的路径来实现的,它返回一个 webWorker 的实例对象,该对象是主线程与该线程通信的桥梁
let worker = new Woker ('webWorker.js')
webWorker 在主线程和子线程之间实现通信的方法有两个:
// 监听一个线程向另一个发送的消息并执行指定方法
// 回调方法接受一个 event 参数,event.data 为接受到的数据
onmessage = (event) => {}
// 一个线程向另一个线程发送消息
postMessage(data)
实际使用时可以像下面这样使用:
/**
* 主线程
*/
let worker = new Worker ('worker.js')
worker.onmessage = (e) => {
console.log(e.data) // I post a message to main thread
}
worker.postMessage('main thread got a message')
/**
* 子线程 worker.js
*/
onmessage = (e) => {
console.log(e.data) // main thread got a message
}
postMessage('I post a message to main thread')
终止 webWorker
// 在主线程中终止
worker.terminate()
// 在子线程中终止自身
self.close()
错误监听
当子线程发生错误时,可以在主线程中监听到该错误
worker.addEventListener('error', (e) => {
console.error(e.filename) // 导致错误的 worker 脚本名称
console.error(e.message) // 错误信息
console.error(e.lineno) // 错误行号
})
引入其他脚本
// 引入一个脚本
importScripts('xxx.js');
// 引入多个脚本
importScripts('aaa.js', 'bbb.js', 'ccc.js');
importScripts 会按顺序加载每一个脚本,当有任何失败或者错误时,会抛出 SYNTAX_ERR 异常
共享线程的使用
主线程中创建一个共享线程
let shareWorker = new SharedWorker ('shareWorker.js')
shareWorker.port.start()
shareWorker.port.postMessage('...')
shareWorker.port.onmessage = (e) => {...}
子线程 shareWorker.js
onconnect = (e) => {
let port = e.ports[0]
port.addEventListener('message', (e) => {
console.log(e.data[0])
port.postMessage(...);
});
port.start();
}
postMseeage 方法
postMseeage 传递数据的过程其实是一个值拷贝的过程,会现将数据 JSON.stringify 之后再 JSON.parse
postMseeage 也可以传送二进制数据,但是当数据过大时,由于值拷贝,浏览器会再生成一个该文件的拷贝,这样可能会引起浏览器性能的问题
所以当传输较大数据时,可以直接将数据转移给另一个线程,而不进行值拷贝,只是这样会导致原线程无法再使用这些数据,也能够防止多个线程同时修改的情况发生,这叫做零拷贝
// 指定传输的所有数据都是零拷贝
let data = new ArrayBuffer(64)
worker.postMessage(data, [data])
// 指定数据中的某个属性零拷贝
let obj = {a: 1, b: 2, c: 3}
worker.postMessage(obj, [obj.a, obj.c])
需要注意的是,通过 webWorker 创建的线程的运行环境中没有全局对象 window,也无法访问 DOM / BOM 对象,所以他只能用来执行纯粹的 javascript 计算
当然,他也可以获取到部分浏览器提供的 API,如:
XMLHttpRequest
navigator
location (read only)
setTimeout(), clearTimeout(), setInterval(), clearInterval()
Promise 等等
还有哪些,小伙伴们可以自己去尝试发掘(可以将 self 打印出来看看)
Javascript 基础夯实 —— 使用 webWorker 实现多线程(转)的更多相关文章
- 夯实JavaScript基础之prototype, __proto__, instanceof
function New(f){ return function(){ var o = {'__proto__': f.prototype}; f.apply(o, arguments); retur ...
- 你真的懂JavaScript基础类型吗
夯实Javascript基础. 基本类型有六种: null,undefined,boolean,number,string,symbol. 基本类型的值是保存在栈内存中的简单数据段 基础类型特性 基础 ...
- JavaScript基础
JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...
- 一步步学习javascript基础篇(0):开篇索引
索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...
- 前端之JavaScript基础
前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
- Javascript基础回顾 之(三) 面向对象
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- Javascript基础回顾 之(二) 作用域
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- Javascript基础回顾 之(一) 类型
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
随机推荐
- code+12月月赛 火锅盛宴
时间限制: 2.0 秒 空间限制: 512 MB 题目背景 SkyDec和YJQQQAQ都是Yazid的好朋友.他们都非常喜欢吃火锅.有一天,他们聚在一起,享受一场火锅盛宴. 题目描述 在这场火锅盛宴 ...
- 从map到hash
https://zybuluo.com/ysner/note/1175387 前言 这两种技巧常用于记录和去重量少而分散的状态. 都体现了映射思想. \(map\) 我一般是数组开不下时拿这玩意判重. ...
- C++ 对象的赋值和复制 基本的
对象的赋值 如果对一个类定义了两个或多个对象,则这些对象之间是可以进行赋值,或者说,一个对象的值可以赋值给另一个同类的对象.这里所指的值是指对象中所有数 据的成员的值.对象之间进行赋值是“ ...
- PCB 3D PCB 后续改进与扩展功能一些想法
再次感受到WelGl实现3D效果的震撼, 一.目前功能: Gerber与钻孔 解析 并转为3D实景图,用户360度操控 二.后续改进扩展功能: 1.增加ODB++解析 2. 3D 尺寸标注(外形尺寸, ...
- go函数初级
一.简介 在go语言中,函数的功能是非常强大的,以至于被认为拥有函数式编程语言的多种特性. 二.介绍 1.一个程序中包含了很多的函数:函数式基本的代码块 2.函数编写的顺序是无关紧要的:鉴于可读性的需 ...
- 关于网站图片格式 png,jpg,
小图标用 png 采用无损压缩.可存储透明图片. 适合存储icon, logo 等颜色对比明显,又小的图片. 劣势:索引色数量有限,不适合大图片,颜色层次丰富. 大图片用 jpg 采用了压缩算法,会有 ...
- 在.xls;*.xlsx类型文件的导入(可以导入多条数据)
2018-11-28 17:36:35 需要jar包:poi-3.8-201203026.jar jsp页面: <LINK href="${basePath}plugins/upl ...
- uva11205 The broken pedometer 子集生成
PS:此题我在网上找了很久的题解,发现前面好多题解的都是没有指导意义的.后来终于找到了一篇好的题解. 好的题解的链接:http://blog.csdn.net/u013382399/article/d ...
- word中选择嵌入式时图片被遮住,只显示小部分的解决方法
选中图片,点击如下 选择 行距选项 将行距改为单位行距即可.
- creat-react-app 支持 less
yarn eject yarn add less less-loader config/ webpack.config.dev.js config/ webpack.config.prod.js 文 ...