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. vue学习 第一天 html 基础

    1.web标准的构成: <结构Structure>(对应html文件).<表现Presentation>(对应css文件) 和<行为Behavior>(对应js)三 ...

  2. (性能测试笔记)逻辑IO和物理IO的区别

    IO性能对于一个系统的影响是至关重要的. 一个系统经过多项优化以后,瓶颈往往落在数据库:而数据库经过多种优化以后,瓶颈最终会落到IO.而IO性能的发展,明显落后于CPU的发展.Memchached也好 ...

  3. Mybaties中的报错 Tag name expected解决

    有些时候一些小小的报错可能会没有注意到,等到报错的时候才发现,一个小小的细节也是很重要的,毕竟我们是bug生产员 来看报错的代码 when round((UNIX_TIMESTAMP(DATE_ADD ...

  4. Springboot多数据源使用示例

    1.配置文件 spring.datasource.url=jdbc:mysql://198.168.1.1:3306/user?useUnicode=true&characterEncodin ...

  5. HIVE-文字提取

    regexp_extract(filed,('aaa|bbb|ccc|ddd'),0) 从字段filed中提取含有aaa或bbb或ccc或ddd的string信息

  6. HIVE- lag函数和lead函数

    select date_flag,category_flag,field,LAG(filed, 1) OVER (PARTITION BY category_flag ORDER BY date_fl ...

  7. 用tkinter编写一个获取图片资源的GUI工具

    目录 效果展示 导入tkinter库 窗口属性 按钮和输入框 文本输入框Text 运行 打包成exe文件 源码地址 本文可以学习到以下内容: 使用tkinter的Entry功能获取本地文件夹 使用tk ...

  8. Django安装与启动

    安装 python -m pip install Django  查看版本 python -m django --version打开命令行,cd 到一个你想放置你代码的目录,然后运行以下命令: dja ...

  9. VUE3+VITE 常见问题解决

    reactive解构最深的一层,失去响应性问题 pinia创建的store,使用结构失去响应性 reactive包裹后的对象 重新赋值失去响应性 无法动态引入图片 在computed中传参数 vue3 ...

  10. 记一次Mybatis-Plus动态分表DynamicTableNameInnerInterceptor里无法动态替换表名的坑

    首先上源码 protected String changeTable(String sql) { ExceptionUtils.throwMpe(null == tableNameHandler, & ...