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中调用的话会造成程序假死的情况 于是想 ...
随机推荐
- idea快捷的输出常用语句
sout:System.out.println(); psvm:public static void main(String[] args) {}
- 【实验】VUE依赖版本,遇到就看这里
https://www.cnblogs.com/luomanman/p/15435422.html
- lowcodeEngine 组件面板的拖拽功能
设计器和渲染器处在不同的 Frame 渲染器以单独的 iframe 嵌入,xxx-simulator-renderer 通过和 host进行通信来和设计器打交道,比如点击渲染画布任意一个位置,需要能计 ...
- SQL Server创建dblink跨库查询
dblink是跨库查询的主要手段,在Oracle创建DbLink中已经演示了Oracle中如何创建及使用DbLink,这篇博客看看SQL Server中如何使用. 一.通过图形化界面直接创建 选择当前 ...
- react native 状态栏和安全区域的使用
1. 状态栏组件,react native文档提供了说明.我需要的是设置透明效果,如下图. 代码如下 <StatusBar translucent={true} backgroundColor ...
- python爬虫cookies jar与字典转换
#将CookieJar转为字典: cookies = requests.utils.dict_from_cookiejar(r.cookies) #将字典转为CookieJar: cookies = ...
- 前端之Vue day 05 父子通信、ref、动态组件、插槽、计算监听属性
一.父传子 因为组件间数据不共享,所以我们要想办法打通父子之间的数据联系 自定义属性: 在父级中,给在使用的子组件标签加一个自定义的属性,因为要用到data,所以要写成 :自定义属性名='' #注意, ...
- DDL数据定义--Hive中数据可和表的基本操作(增删改查)
数据库 创建数据库: CREATE DATABASE [ IF NOT EXISTS ] database_name *****IF NOT EXISTS进行判断,避免创建的数据库已经存在的错误 创 ...
- linux安装Elasticsearch的单节点
一.基础环境 操作系统环境:Red Hat Enterprise Linux Server release 6.4 (Santiago) ES版本:elasticsearch-7.8.0-linux- ...
- Kubernetes二进制安装
目录: 操作系统初始化配置 部署docker引擎 部署etcd集群 准备签发证书环境 部署Master组件 部署Worker Node组件 部署CNI网络组件 部署flannel 部署Calico 部 ...