JS学习-Web Worker
Web Worker
在专用workers的情况下,DedicatedWorkerGlobalScope 对象代表了worker的上下文(专用workers是指标准worker仅在单一脚本中被使用;共享worker的上下文是SharedWorkerGlobalScope (en-US)对象)。一个专用worker仅仅能被首次生成它的脚本使用,而共享worker可以同时被多个脚本使用。在一个worker中最主要的你不能做的事情就是直接影响父页面。包括操作父页面的节点以及使用页面中的对象。你只能间接地实现,通过DedicatedWorkerGlobalScope.postMessage (en-US)回传消息给主脚本,然后从主脚本那里执行操作或变化。
Web Workers可以使用的函数和类
- 比较不同类型workers的属性和方法
- APIs available in workers
数据收发
在主页面与 worker 之间传递的数据是通过拷贝,而不是共享来完成的。传递给 worker的对象需要经过序列化,接下来在另一端还需要反序列化。页面与worker不会共享同一个实例,最终的结果就是在每次通信结束时生成了数据的一个副本。大部分浏览器使用结构化拷贝来实现该特性。
结构化拷贝不能拷贝的情况:
- Error以及Function对象是不能被结构化克隆算法复制的;如果你尝试这样子去做,这会导致抛出 DATA_CLONE_ERR的异常。
- 企图去克隆DOM上游同样会引发DATA_CLONE_ERROR异常。
- 对象的某些特定参数也不会被保留
- RegExp对象的lastIndex主轴不会被保留
- 例如,如果一个对象使用属性标记为readonly,则它将被复制为read-write,因为这是默认的情况下。
- 原形链上的属性也不会被追踪以及复制。
专用worker
特性检测
if (window.Worker) { ... }
引入脚本与库
importScripts(); /* 什么都不引入 */
importScripts('foo.js'); /* 只引入 "foo.js" */
importScripts('foo.js', 'bar.js'); /* 引入两个脚本 */
生成专用worker
// main.js
var myWorker = new Worker('worker.js');
消息收发
// postMessage
myWorker.postMessage([first.value,second.value]);
// onmessage
myWorker.onmessage = function(e) {
result.textContent = e.data;
console.log('Message received from worker');
}// worker.js
onmessage = function(e) {
console.log('Message received from main script');
postMessage('Result: ' + (e.data));
}
终止worker
// main.js
myWorker.terminate();
// worker.js
close()
处理错误
onerror = function(e){
console.log(e)
}// e:{message:'',filename:'',lineno(行号):''}
共享worker
生成共享worker
// worker.js
port.start();
// main.js
var myWorker = new SharedWorker('worker.js');
myWorker.port.start(); // 父级线程中的调用
消息收发
// worker.js
onconnect = function(e) {
var port = e.ports[0];
port.onmessage = function(e) {
port.postMessage('Result: ' + (e.data));
}
}
//main.js
myWorker.port.postMessage([squareNumber.value]);
myWorker.port.onmessage = function(e) {
result2.textContent = e.data;
console.log('Message received from worker');
}
嵌入式 worker
<script type="text/js-worker">
// 该脚本不会被 JS 引擎解析,因为它的 mime-type 是 text/js-worker。
var myVar = "Hello World!";
// 剩下的 worker 代码写到这里。
</script>
<script type="text/javascript">
function pageLog (sMsg) {
// 使用 fragment:这样浏览器只会进行一次渲染/重排。
var oFragm = document.createDocumentFragment();
oFragm.appendChild(document.createTextNode(sMsg));
oFragm.appendChild(document.createElement("br"));
document.querySelector("#logDisplay").appendChild(oFragm);
}
</script>
<script type="text/js-worker">
onmessage = function (oEvent) {
postMessage(myVar);
};
// 剩下的 worker 代码写到这里。
</script>
<script type="text/javascript">
// 该脚本会被 JS 引擎解析,因为它的 mime-type 是 text/javascript。
// ...使用 Blob...:
var queryWorker = Array.prototype.map.call(
document.querySelectorAll("script[type=\"text\/js-worker\"]";
var queryWorkerContent = queryWorker,
function (oScript) {
return oScript.textContent;
})
)
var blob = new Blob(queryWorkerJs,{type: "text/javascript"});
// 创建一个新的 document.worker 属性,包含所有 "text/js-worker" 脚本。
document.worker = new Worker(window.URL.createObjectURL(blob));
document.worker.onmessage = function (oEvent) {
pageLog("Received: " + oEvent.data);
};
// 启动 worker.
window.onload = function() {
document.worker.postMessage("");
};
</script>
可以将一个函数转换为blob,然后为这个blob生成URL对象。
function fn2workerURL(fn) {
var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'})
return URL.createObjectURL(blob)
}
内容安全策略
为了给worker指定内容安全策略,必须为发送worker代码的请求本身加上一个 内容安全策略。
传递数据的例子
- 创建一个通用的 「异步 eval()」
- 传输 JSON 的高级方式和创建一个交换系统
- 在后台执行运算
通过转让所有权(可转让对象)来传递数据
/* 当你将一个 ArrayBuffer 对象从主应用转让到 Worker 中,原始的 ArrayBuffer 被清除并且无法使用。它包含的内容会(完整无差的)传递给 Worker 上下文。 */
// Create a 32MB "file" and fill it.
var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
for (var i = 0; i < uInt8Array .length; ++i) {
uInt8Array[i] = i;
}//uInt8Array.buffer ArrayBuffer(33554432)
worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
JS学习-Web Worker的更多相关文章
- Node.js学习 - Web Server
Client - 客户端,一般指浏览器,浏览器可以通过 HTTP 协议向服务器请求数据. Server - 服务端,一般指 Web 服务器,可以接收客户端请求,并向客户端发送响应数据. Busines ...
- Web worker 与JS中异步编程的对比
0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何 ...
- HTML5学习笔记(六)web worker
当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成.web worker 是运行在后台的 JavaScript,不会影响页面的性能,页面可以响应. 在创建 web worker ...
- HTML5:web socket 和 web worker
a:hover { cursor: pointer } 做练习遇到了一个选择题,是关于web worker的,问web worker会不会影响页面性能?补习功课之后,答案是不会影响. 查阅了相关资料学 ...
- 【转向Javascript系列】深入理解Web Worker
本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/11/deep-in-web-worker/ 上一篇文章<从setTimeout说事件循 ...
- Web Worker是什么
.Web Worker是什么 Web Worker 是HTML5标准的一部分,这一规范定义了一套 API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中.Web Worker 规范 ...
- 快速使用node.js进行web开发
首先关于node.js的学习,这里推荐一本比较好的教程,nodejs web开发指南,该书通俗易懂地将node.js语言特性讲解完之后,又从一个项目角度带领读者使用node.js学习web开发.相信这 ...
- JS线程模型&Web Worker
js线程模型 客户端javascript是单线程,浏览器无法同时运行两个事件处理程序 设计为单线程的理论是,客户端的javascript函数必须不能运行太长时间,否则会导致web浏览器无法对用户输入做 ...
- web Worker使js实现‘多线程’?
大家都知道js是单线程的,在上一段js执行结束之前,后面的js绝对不会执行,那么为什么标题说js实现‘多线程’,虽然说加了引号,可是标题也不能乱写不是,可恶的标题党? 姑且抛开标题不说,先说我们经常会 ...
- javascript 多线程Web Worker不引用外部js文件的方法
最近在Android开发中 Webview通过调用JavascriptInterface的方式与App交互 在交互的过程中,有些App上的操作时间会比较长,Web中调用的话会造成程序假死的情况 于是想 ...
随机推荐
- 如何用adb连接android手机
如何用adb连接android手机 以下为手机"root"情况下操作....手机没root请拉到笔记最后,有解决方法 利用adb来连接手机, 有两种方式: wifi usb 通过w ...
- ubuntu 安装php7.2 oracle扩展
一:介绍 php要连接访问oracle需要安装三个东西 1:Oracle Instant Client:即时客户端库 2:php的Oracle数据库扩展:oci8 3:php连接pdo的oci扩展:p ...
- 解决Vue刷新后页面数据丢失的问题(sessionStorage和localStorage的用法)
一.为什么刷新后数据会丢失 vuex存储的数据只是在页面中,相当于全局变量,页面刷新的时候vuex里的数据会重新初始化,导致数据丢失. 因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重 ...
- Vue3.0 实现数据双向绑定的方法
ue3.0 是通过Proxy实现的数据双向绑定,Proxy是ES6中新增的一个特性,实现的过程是在目标对象之前设置了一层"拦截",外界对该对象的访问,都必须先通过这层拦截,因此提供 ...
- PLSQL DEVELOPER使用
一.下载plsql developer.(oracle官网下载地址:https://www.oracle.com/technetwork/topics/winsoft-085727.html) 二.下 ...
- 【React】React项目实践中的问题
报错'react-scripts' 不是内部或外部命令,也不是可运行的程序 React新建脚手架项目,在目录下添加了public\index.html,src\App.js,index.js文件,除此 ...
- js引入样式资源报错
如上图,import这几个样式资源为什么会报错,怎么解决呢,而且那个jquery-ui之前也会报错但是现在刷新一遍他又不报错了其他的css文件报错 图片转代码服务由CSDN问答提供 功能建议 im ...
- new与delete只能被重载为成员函数;而<<等只能被重载为非成员函数
链接:https://www.nowcoder.com/questionTerminal/5760864337084de6891a9944f41e60f4来源:牛客网 应用程序可以将重载的new/de ...
- 记录POI导入时单元格下拉框两种实现方式(excel数据有效性)
如果下拉选项字符少于225 使用方式1 public static HSSFSheet setHSSFValidation(HSSFSheet sheet, String[] textlist, in ...
- 关于matlab2011b 32bit无法成功激活
matlab2011b版本已经很少见了 下载链接:Matlab_R2011B.Win32.iso_免费高速下载|百度网盘-分享无限制 (baidu.com) 解决办法:(参考原博) (43条消息) M ...