摘要:专用线程不仅仅支持传输二进制数据,也支持结构化的数据格式。但是我们所开启的新的也就是子线程,并不支持操作页面的。共享线程共享线程是为了避免线程的重复创建和销毁过程,降低了系统性能的消耗,共享线程可以同时有多个页面的线程链接。
原文链接
Web Worker 详细介绍 - 原文链接
[TOC]
1、简介我们都知道JavaScript这个语言在执行的时候是采用单线程进行执行的,也就是说在同一时间只能做一件事,这也和这门语言有很大的关系,采用同步执行的方式进行运行,如果出现阻塞,那么后面的代码将不会执行,HTML5则提出了web Worker标准,表示JavaScript允许有多个线程,但是子线程完全受主线程的控制,切子线程不能操作DOM,只有主线程可以操作DOM,所以以主线程为主的单线程执行原理成了JavaScript这门语言的核心。关于JavaScript的运行机制可以参考阮一峰的文章JavaScript 运行机制详解:再谈Event Loop
2、Web Worker下面我们来说说web worker到底是什么,简单明了的一句话其实就是在Javascript单线程执行的基础上,开启一个子线程,进行程序处理,而不影响主线程的执行,当子线程执行完毕之后再回到主线程上,在这个过程中并不影响主线程的执行过程。
举个例子:
传统情况下,执行下面的代码后,整个页面都会被冻结,由于javascript是单线程处理,如下代码已经完全组塞了后续的执行
while(true){}
如果换一种方式,我们通过开启一个新的线程来执行这段代码,将他放在一个多带带的worker.js文件中,在主线程执行以下代码。
var worker = new Worker("worker.js")
在创建线程的时候需要给实例化的Worker传入唯一一个参数,指向一个javascript文件资源的url或者Blob对象(Blob对象就是一个包含有只读原始数据类文件对象),调用这个构造函数之后,一个线程就被创建了,如下:
var worker = new Worker("worker.js"); var worker = new Worker(blob);
Web Worker的基本原理就是在当前的主线程中加载一个只读文件来创建一个新的线程,两个线程同时存在,且互不阻塞,并且在子线程与主线程之间提供了数据交换的接口postMessage和onmessage。来进行发送数据和接收数据。其数据格式可以为结构化数据(JSON等);
当我们创建了一个worker实例之后,我们可以通过如下两种方式来发送数据:
var worker = new Worker("worker.js"); //实例化对象 //第一种传递方式 worker.postMessage(message,taransferList); //第二种传递方式 worker.postMessage({ operation: "list_all_users", //ArrayBuffer object input: buffer, threshold: 0.8, }, [buffer]);
如果要想一个专用线程发送数据,那么我们需要使用线程中的 postMessage 方法。专用线程不仅仅支持传输二进制数据,也支持结构化的 JavaScript 数据格式。在这里有一点需要注意,为了高效地传输 ArrayBuffer 对象数据,需要在 postMessage 方法中的第二个参数中指定它。
同时我们如果需要接收某个线程传来的数据可以使用onmessage来进行接收,方法如下:
//方法一 worker.onmessage = function(event){ var data = event.data; //通过event.data来获取传入的参数 } //方法二 worker.addEventListener("message",target);
下面是一段运行在chrome中的参数传递方式:
index.html
webWorker
worker.js
onmessage = function (e) { console.log(e.data); postMessage("2222") };
此时我们的浏览器打印出的log是如下:
上面我们已经说了创建一个新的线程、传递数据、接收数据的方法,下面再次做一个精简的回顾。
var worker = new Worker("worker.js")
worker.postMessage("text");
worker.onmessage = function (e) { var message = e.data; };
worker.onerror = function(e){ console.log("error at "+e.filename ":" + e.lineno + e.message) }
worker.terminate();
importScripts("./utils/base64.js","./utils/map.js"...)
需要注意的是importScripts是同步方法,一旦importScripts方法返回就可以开始使用载入的脚本,而不需要回调函数。4、Worker作用域
当我们创建一个新的worker时,改代码会运行在一个全新的javascript的环境中(WorkerGlobalScope)运行,是完全和创建worker的脚本隔离,这时我们可以吧创建新worker的脚本叫做主线程,而被创建的新的worker叫做子线程。
WorkerGlobalScope是worker的全局对象,所以它包含所有核心javascript全局对象拥有的属性如JSON等,window的一些属性,也拥有类似于XMLHttpRequest()等。
但是我们所开启的新的worker也就是子线程,并不支持操作页面的DOM。
5、共享线程 SharedWorker共享线程是为了避免线程的重复创建和销毁过程,降低了系统性能的消耗,共享线程SharedWorker可以同时有多个页面的线程链接。
使用SharedWorker创建共享线程,也需要提供一个javascript脚本文件的URL地址或Blob,该脚本文件中包含了我们在线程中需要执行的代码,如下:
var worker = new SharedWorker("sharedworker.js");
共享线程也使用了message事件监听线程消息,但使用SharedWorker对象的port属性与线程通信如下。
worker.port.onmessage = function(e){ ... }
同时我们也可以使用SharedWorker对象的port属性向共享线程发送消息如下。
worker.port.postMessage("message");摘录
文章大部分类容摘自《指尖上行》一书
参考文献
1、JavaScript 运行机制详解:再谈Event Loop —— 阮一峰
2、深入 HTML5 Web Worker 应用实践:多线程编程
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/90341.html
摘要:在上看到发的视频被狂转开始注意之前几乎对这个词语没有印象看到是在的演讲还以为是新技术在上找一下这次好多个视频是关于的视频的内容主要是讲网站优化分别用做例子可惜没有大概要等小右补方案应该没有问题从视频看优化的效果非常显著本来好几秒的 在 Twitter 上看到 Addy Osmani 发的视频被狂转, 开始注意https://twitter.com/addyosmani/status/7...
摘要:的另一个核心特性,苹果表示也正在开发中,按开发进度可能几个月后就能与我们见面。是基于的本地化数据库,支持以及浏览器环境。 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎关注【前端之巅】微信公众号(ID: frontshow),及时获取前端每周清单。 本期是 2017 年的最后一...
摘要:前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎关注【前端之巅】微信公众号(ID:frontshow),及时获取前端每周清单;本文则是对于...
摘要:背景前一阵子开发的项目导入由于自己的代码问题引起了个性能问题一个的文件转换成数据大概要耗时虽然后面发现是某个使用频率非常高的函数内部用了构造函数造成的所以这里顺便提醒一下如果你很在乎几毫秒的差距的话建议谨慎使用哈但是在优化的过程中一度怀疑是 背景 前一阵子开发的项目 pptx 导入, 由于自己的代码问题,引起了个性能问题,一个 40p 的 pptx 文件,转换成 json 数据,大概要...
阅读 2394·2021-11-11 16:54
阅读 1203·2021-09-22 15:23
阅读 3643·2021-09-07 09:59
阅读 1989·2021-09-02 15:41
阅读 3282·2021-08-17 10:13
阅读 3036·2019-08-30 15:53
阅读 1234·2019-08-30 13:57
阅读 1209·2019-08-29 15:16