学习webworker
1. 什么是webworker
理论多代码少的一个新特性
MDN是这样说的
Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面
一个worker是使用一个构造函数创建的一个对象(e.g. Worker()) 运行一个命名的JavaScript文件
这个文件包含将在工作线程中运行的代码;
workers 运行在另一个全局上下文中,不同于当前的window
因此,使用 window快捷方式获取当前全局的范围 (而不是self) 在一个 Worker 内将返回错误
可以这样理解:
- 创建Worker时,JS引擎向浏览器申请开一个子线程(子线程是浏览器开的,完全受主线程控制,而且不能操作DOM)
- JS引擎线程与worker线程间通过特定的方式通信(postMessage API,需要通过序列化对象来与线程交互特定的数据)
如果有非常耗时的cpu密集型工作,可以单独开一个Worker线程,因为里面不管如何翻天覆地都不会影响JS引擎主线程,
只待计算出结果后,将结果通信给主线程即可
而且注意下,JS引擎是单线程的,这一点的本质仍然未改变,Worker可以理解是浏览器给JS引擎开的外挂,专门用来解决那些大量计算问题。
2. webworker帮助我们解决了什么问题,该如何去使用webworker呢
一些非常耗时的工作会阻塞js的代码,这种情况就需要使用这个东西。
非常耗时的cpu密集型工作!!!
举个例子:我们在两个button中间加一段耗时的script代码。
<body><button>111</button><script src="./1.js"></script><button>222</button></body>
1.js的耗时代码:
var start = new Date().getTime()do {var end = new Date().getTime();} while (end - start < 3000)console.log("5秒执行结束");
这里我们一般不这样写代码,但是确实一个很好的线程阻塞的问题,因为js的单线程,浏览器的渲染引擎将第一个button渲染结束的时候,执行了script脚本,cpu被js引擎占用,如果这个耗时操作不结束,渲染引擎将无法继续工作,导致页面不能正常的工作。
A. 开启worker
我们这个时候开启一个Worker即可解决这个问题。(注意这个不能读取本地的js文件,否则会报错,只能是服务端的js脚本文件)
<body><button>111</button><script>// 创建新的线程执行05.jsvar worker= new Worker("./1.js")</script><button>222</button></body>
只是执行代码还是有些单薄的,我们还需要实现主线程与worker线程之间的通讯
B. 主线程 -> worker线程
主线程调用worker.postMessage()方法,向 Worker 发消息。
worker.postMessage('Hello World');worker.postMessage({method: 'echo', args: ['Work']});
主线程通过worker.onmessage指定监听函数,接收子线程发回来的消息。
worker.onmessage = function (event) {console.log('Received message ' + event.data);doSomething();}function doSomething() {// 执行任务worker.postMessage('Work done!');}
Worker 完成任务以后,主线程就可以把它关掉。
worker.terminate();
填坑举例:这个监听一般都是异步的所以我们在主线程关闭的时候要在onmessage中将数据处理完成之后关闭。
// 创建新的线程执行05.jsvar worker = new Worker("./1.js")// 向worker发数据worker.postMessage("123")// 接收worker的数据worker.onmessage = function(event) {console.log("主Received message:" + event.data);wworkerterminate();}// w.terminate(); // 消息无法正常的传递,我们在传递前就关掉了
C. worker线程 -> 主线程
Worker 线程内部需要有一个监听函数,监听message事件,监听从主线程来的消息
self.addEventListener('message', function (e) {self.postMessage('You said: ' + e.data);}, false);
上面代码中,self代表子线程自身,即子线程的全局对象。因此,等同于下面两种写法。
// 写法一this.addEventListener('message', function (e) {this.postMessage('You said: ' + e.data);}, false);// 写法二addEventListener('message', function (e) {postMessage('You said: ' + e.data);}, false);
子线程调用worker.postMessage()方法,向 主线程发消息。
postMessage("456")
子线程接收主线程的消息,并且发送给主线程结果,然后关闭自己
onmessage = function(event) {console.log("新Received message:" + event.data);postMessage("456")self.close()}
子线程关闭自己
self.close();
D. 关闭 Worker
使用完毕,为了节省系统资源,必须关闭 Worker。
// 主线程worker.terminate();// Worker 线程self.close();
以上就已经完成了worker最基本的使用了。
还在阮一峰老师的博客上看到其他的两个方法在这里搬运一下
1. 在 Worker 内加载脚本
Worker 内部如果要加载其他脚本,有一个专门的方法importScripts()。
importScripts('script1.js');
该方法可以同时加载多个脚本。
importScripts('script1.js', 'script2.js');
2. 错误处理
主线程可以监听 Worker 是否发生错误。如果发生错误,Worker 会触发主线程的error事件。
worker.onerror(function (e) {console.log(['ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message].join(''));});// 或者worker.addEventListener('error', function (e) {// ...});
到这里,最基本的webworker的使用就结束了,希望大家能有所收获。
参考文档:
进程线程:https://segmentfault.com/a/1190000012925872
阮一峰:https://www.ruanyifeng.com/blog/2018/07/web-worker.html
学习webworker相关推荐
- web-worker的学习
Web Worker 作用 Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行.在主线程运行的同时,Worker ...
- Puppeteer 学习笔记及基本用法
Puppeteer 学习笔记及基本用法 Puppeteer 安装 语法 基本语法 API 分层结构 加载导航页面 等待元素.请求.响应 自定义等待 元素定位 用户模拟操作 请求拦截 获取 WebSoc ...
- 学习underscore源码整体架构,打造属于自己的函数式编程类库
前言 上一篇文章写了 jQuery整体架构,学习 jQuery 源码整体架构,打造属于自己的 js 类库 虽然看过挺多 underscore.js分析类的文章,但总感觉少点什么.这也许就是纸上得来终觉 ...
- 【学习笔记】前端开发面试锦集
链接地址:https://microzz.com/2017/02/10/interview/ 前端还是一个年轻的行业,新的行业标准, 框架, 库都不断在更新和新增,正如赫门在2015深JS大会上的&l ...
- 石墨文档代码学习笔记分享
代码学习: 前后端对json的简单处理 Java和数据库锁的问题简单介绍 Java后端 二维码 加密 xml解析 发送简单邮件等常用功能. Java后端日志logback 文件的上传和下载 freem ...
- 整理学习:100多道前端面试题(一起加油,且行且珍惜)
前言 当你准备去面试时,你不妨看一些面试的题目(推荐掘金)来提醒自己究竟掌握得怎么样,比如 题目 笔者最近一边写项目,一边整理前端面试题,打算完成项目就差不多去实习了- 没有特别宏大的目标,打算安安分 ...
- 前端一班:HTML5当天学习总结-摘抄张果博客园
一.初步了解HTML5,相关涉及技术以及行业前景 二.HTML5特性 HTML5 八个特性类别对应的8个Logo 语义化.离线&存储.设备访问.通信 多媒体.图形和特效.性能和集成.呈现(CS ...
- typeScript学习笔记day02——小肉包
typeScript学习笔记 class3 : 2021.02.24 一.TS编译选项 自动编译文件 编译文件时,使用-w指令后,YS编译器会自动监视文件变化,并在文件发生变化时对文件进行重新编译. ...
- babylon 画线_【温故知新】——BABYLON.js学习之路·前辈经验(一)
前言:公司用BABYLON作为主要的前端引擎,同事们在长时间的项目实践中摸索到有关BABYLON的学习路径和问题解决方法,这里只作为温故知新. 一.快速学习BABYLON 二.需要掌握的基本技能 1. ...
- 如何学习HTML5?
如何 学习 HTML5 ?这个话题,问的人很多,随便百度一下就能看到各种各样的回答.不过感觉每种回答都不给力.下面我给出一个自己理解的HTML5学习的路线图,按照这个路线图学习以后,一般的HTML5项 ...
最新文章
- web项目数据存入mysql数据库中文乱码问题
- 磁悬浮地球仪控制初步测试
- angularJs的学习笔记
- python小程序源代码-Python小项目:开发一个动态时钟小程序(附源码)
- Vue(ES6)中的data属性为什么不能是一个对象?
- matlab立体坐标定位_【半导光电】基于光电探测器的激光章动定位算法(二)
- 手机百度输入法的用户体验
- java不建议用全局变量吗_不要使用全局变量, ThreadLocal也不行
- Mozilla Firefox 在用户访问被黑客攻击的网站时发出警告
- 电子商务商品供应链概论
- 如何使用Mac的屏幕时间功能限制访问网站?
- stm32 操作W25Q256 W25Q16 spi flash
- Python——Python Enhancement Proposal
- python安装包报错解决方案
- poj解题报告——poj 1528 Perfection
- CHIL-SQL-CREATE TABLE 语句
- 高数中一点导数大于0,能否推出函数在0这个去心邻域单增?
- 轻量级研发知识管理--如何帮助研发人员建设过程资产
- 如何把录音转换成文字?这几个方法可以轻松解决录音转文字
- oracle列分区,Oracle数据库分区--实例
热门文章
- python eml解析_如何在python中读取eml文件?
- python绘制每日的时序图_GitHub - wavous/Python-100-Days: Python - 100天从新手到大师
- 靶向肿瘤代谢,助力攻克癌症
- Android进程间通信系列-----------进程间的数据传递载体Parcel
- 程序媛们,女神节快乐~
- 6.5 发散思维能力
- 淘宝秒杀半价前N名半价商品
- fits文件读取代码
- 我喜欢的学科计算机 英文作文,我喜欢的学科写英语作文40字
- 浏览器点击后退提示_当点击浏览器后退时会发生什么