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. php 关于 json字符串使用json_decode 转数组为空

    项目中遇见一个之前没有遇见的问题,就是 转化一个json字符串为数组时 为空,解决办法是使用 htmlspecialchars_decode 处理一下json字符串 然后 再使用 json_decod ...

  2. RockyLinux8.7 制作OpenSSH9.2 rpm包

    由于系统原装的openssh存在高危的漏洞,安全扫描不过,故制作出最新版本的rpm包修复openssh高危漏洞. 1.安装基础环境工具 dnf install wget make gcc perl r ...

  3. C3861: “CoInitialize”“CoUninitialize”: 找不到标识符

    error C3861: "CoInitialize": 找不到标识符error C3861: "CoUninitialize": 找不到标识符 包含头文件和链 ...

  4. CCIE DC Multicast Part 3.

    Hi Guys! Here is part 3 of the Multicast Tutorials, Hopefully you have read the two previous posts h ...

  5. csdn 复制

    $("#content_views pre").css("user-select","text"); $("#content_vi ...

  6. sxt_(015)_request处理表单数据及乱码

    一.request处理表单数据及乱码 1.1 处理单个表单数据用request.getParameter("x"); 1.2 处理多个表单(checkbox.select)数据用r ...

  7. 基于注解的AOP

    1.引入依赖 <!--spring aop依赖--> <dependency> <groupId>org.springframework</groupId&g ...

  8. 视频直播源码,js实现节流和防抖

    视频直播源码,js实现节流和防抖 防抖: 就是指连续触发事件但是在设定的一段时间内中只执行最后后一次,例如:设定1000毫秒执行,当你触发事件了,他会1000毫秒后执行,但是在还剩500毫秒的时候你又 ...

  9. go 的 wire 依赖注入

    首先安装 wire 工具 go install github.com/google/wire/cmd/wire@latest go 文件 package main import ( "fmt ...

  10. AWT+Swing区别

    AWT 是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交互的接口.AWT 中的图形函数与操作系统所提供的图形函数之间有着一一对应的关 ...