Web Worker

在专用workers的情况下,DedicatedWorkerGlobalScope 对象代表了worker的上下文(专用workers是指标准worker仅在单一脚本中被使用;共享worker的上下文是SharedWorkerGlobalScope (en-US)对象)。一个专用worker仅仅能被首次生成它的脚本使用,而共享worker可以同时被多个脚本使用。在一个worker中最主要的你不能做的事情就是直接影响父页面。包括操作父页面的节点以及使用页面中的对象。你只能间接地实现,通过DedicatedWorkerGlobalScope.postMessage (en-US)回传消息给主脚本,然后从主脚本那里执行操作或变化。

Web Workers可以使用的函数和类

  1. 比较不同类型workers的属性和方法
  2. 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代码的请求本身加上一个 内容安全策略。

传递数据的例子

  1. 创建一个通用的 「异步 eval()」
  2. 传输 JSON 的高级方式和创建一个交换系统
  3. 在后台执行运算

通过转让所有权(可转让对象)来传递数据

/* 当你将一个 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的更多相关文章

  1. Node.js学习 - Web Server

    Client - 客户端,一般指浏览器,浏览器可以通过 HTTP 协议向服务器请求数据. Server - 服务端,一般指 Web 服务器,可以接收客户端请求,并向客户端发送响应数据. Busines ...

  2. Web worker 与JS中异步编程的对比

    0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何 ...

  3. HTML5学习笔记(六)web worker

    当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成.web worker 是运行在后台的 JavaScript,不会影响页面的性能,页面可以响应. 在创建 web worker ...

  4. HTML5:web socket 和 web worker

    a:hover { cursor: pointer } 做练习遇到了一个选择题,是关于web worker的,问web worker会不会影响页面性能?补习功课之后,答案是不会影响. 查阅了相关资料学 ...

  5. 【转向Javascript系列】深入理解Web Worker

    本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/11/deep-in-web-worker/ 上一篇文章<从setTimeout说事件循 ...

  6. Web Worker是什么

    .Web Worker是什么 Web Worker 是HTML5标准的一部分,这一规范定义了一套 API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中.Web Worker 规范 ...

  7. 快速使用node.js进行web开发

    首先关于node.js的学习,这里推荐一本比较好的教程,nodejs web开发指南,该书通俗易懂地将node.js语言特性讲解完之后,又从一个项目角度带领读者使用node.js学习web开发.相信这 ...

  8. JS线程模型&Web Worker

    js线程模型 客户端javascript是单线程,浏览器无法同时运行两个事件处理程序 设计为单线程的理论是,客户端的javascript函数必须不能运行太长时间,否则会导致web浏览器无法对用户输入做 ...

  9. web Worker使js实现‘多线程’?

    大家都知道js是单线程的,在上一段js执行结束之前,后面的js绝对不会执行,那么为什么标题说js实现‘多线程’,虽然说加了引号,可是标题也不能乱写不是,可恶的标题党? 姑且抛开标题不说,先说我们经常会 ...

  10. javascript 多线程Web Worker不引用外部js文件的方法

    最近在Android开发中 Webview通过调用JavascriptInterface的方式与App交互 在交互的过程中,有些App上的操作时间会比较长,Web中调用的话会造成程序假死的情况 于是想 ...

随机推荐

  1. docker 部署minio

    1 docker pull minio/minio:RELEASE.2022-08-26T19-53-15Z 2 docker run -p 9000:9000 -p 9090:9090  --nam ...

  2. Win10系统将bat文件注册成服务

    代码语法: sc create ServiceName binPath= 路径 start= auto 示例语句: sc create Tomcat binPath= F:/tomcat/bin/st ...

  3. vue2和vue3配置全局自定义参数及vue3动态绑定ref

    在 Vue2.x 中我们可以通过 Vue.prototype 添加全局属性 property.但是在 Vue3.x 中需要将 Vue.prototype 替换为 config.globalProper ...

  4. 085_JS Promise

    js对undefined的处理  https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000 ...

  5. python_异常处理(try except)

    1,异常捕获 异常捕获的字段为python解释报错的最后一行的第一个单词.使用try方法,程序报错时,可以使用except方法匹配报错的异常关键字,继续except下方定义的代码,从而保证代码可以正常 ...

  6. 宝塔邮局-并解决A纪录解析失败问题

    为什么一定要用这个邮局呢,只要是方便,在宝塔面板直接安装就行了. 使用教程如下: https://www.bt.cn/bbs/thread-87496-1-1.html 有一个BUG本来已经设置好了, ...

  7. WebSocket 基本使用

    1. 引入 WebSocket 包 2. 2.最后测试 WebSocket 谷歌浏览器 F12 ,在 Console 控制台 输入以下测试链接,然后回车测试. ws = new WebSocket() ...

  8. gin框架笔记

    1.实现http://127.0.0.1:8080/index.html的形式访问前端页面.gin-contrib/static 使用中间件的方式判断是否存在该静态文件.fileserver 是一个 ...

  9. jwt二次加密失败原因(Bad “options.expiresIn“ option the payload already has an “exp“ property.)

    在写vue+nodejs项目的校验token时,出现了次错误 然后想了想问题所在: 第一次加密的时候使用jwt.sign(value,秘钥,{}),会返回一个字符串,然后当前端跳转别的发送请求时,会将 ...

  10. 【rocky linux】firewalld切换到iptables 以及Failed to start IPv4 firewall with iptables.

    关闭[firewalld],安装iptables并启动 #关闭自带 firewall systemctl stop firewalld systemctl mask firewalld#显示当前 fi ...