• worker概述
  • worker基本使用
  • window下的postMessage
  • worker多线程的应用

一、worker概述

web worker实际上是开启js异步执行的一种方式。在html5之前有事件、定时器、http请求三种异步机制,js本身并不能主动将一块代码使用异步的方式执行,worker的出现填补了js在非事件、定时器、http请求的情况下可以主动开启js代码的异步执行。worker有自己独立的线程,并非像前面三个异步机制那样的回调函数。所以,worker线程一旦建立成功,就会始终运行,并不会像前面三个异步机制那样被主线程打断,主线程与辅助线程(worker)之间通过消息事件通讯。

web worker相关手册与博客:

阮一峰网络日志:http://www.ruanyifeng.com/blog/2018/07/web-worker.html

MDN手册:https://developer.mozilla.org/zh-CN/docs/Web/API/Worker

developer博客:https://www.developer.com/lang/jscript/7-things-you-need-to-know-about-web-workers.html

上一篇博客的翻译版:https://blog.csdn.net/shenlei19911210/article/details/49779613

web worker使用注意事项:

1.同源限制:分配worker线程运行脚本文件,必须与主线程的脚本文件同源。

2.DOM限制:worker线程所在的全局对象,与主线程不一样,不能读取所在网页的DOM对象,也无法使用document 、 window 、parent这些对象。但是worker线程可以使用navigator对象和location对象。

3.通信联系:worker线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。

4.脚本限制:worker线程不能执行alert()方法和cnfirm()方法,但可以使用XMLHttpRequest对象发送AJAX请求。

5.文件限制:worker线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本必须来自网络。

二、worker的基本使用

2.1在主线程中开启一个辅助线程:

var worker = new Worker('./worker.js'); //在主线程的中开启辅助线程(传入辅助线程的文件路径)

2.2主线程向辅助线程发送消息:

 var data = {type:'sum',num:1000}//测试Function类型的值不能传递
worker.postMessage(data);//通过postMessage方法传递给辅助线程

2.3辅助线程接收主线程的消息:

 this.onmessage = function(e){//在辅助线程中通过onmessage事件监听主线程postMessage发送过来的消息
console.log(e);//通过事件元对象中的data接收主线程发送过来的数据
console.log(e.data.num)
}

2.4.辅助线程向主线程提交工作(第5行代码):

 this.onmessage = function(e){//在辅助线程中通过onmessage事件监听主线程postMessage发送过来的消息
var submitWorker = null;
if(e.data.type == 'sum'){
submitWorker = sum(e.data.num); //辅助线程处理业务
this.postMessage(submitWorker); //辅助线程通过postMessage方法向主线程提交工作
}
}
function sum(num){
var sumVal = 0;
for(var i = 0; i < num; i++){
sumVal +=i;
}
return sumVal;
}

2.5主线程接收辅助线程的工作:

 worker.onmessage = function(e){//主线程通过onmessage监听接收辅助线程的消息
console.log(e);// 同样通过事件元对象的data获取辅助线程传递过来的数据
console.log(e.data);//
}

2.6主线程辞退辅助线程与辅助线程主动关闭线程:

 worker.terminate(); //主线程主动关闭辅助线程worker (辞退后不在接收辅助线程的消息)
this.close(); //辅助线程主动关闭线程(关闭后不再向主线程发送消息)

以上示例的全部代码,请注意需要在网络服务下测试,因为worker必须来自网络。

 //indexWorker.html(主线程代码)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>worker</title>
<link rel="stylesheet" href="">
</head>
<body>
<script>
var worker = new Worker('./worker.js');
var data = {
type:'sum',
num:1000
}
worker.postMessage(data);//主线程向辅助线程发送消息
worker.onmessage = function(e){//主线程接收辅助线程的消息
console.log(e);// 同样通过事件元对象的data获取辅助线程传递过来的数据
console.log(e.data);//
// worker.terminate(); //主线程主动关闭辅助线程worker
} </script>
</body>
</html> //worker.js(辅助线程脚本代码)
this.onmessage = function(e){//在辅助线程中通过onmessage事件监听主线程postMessage发送过来的消息
// console.log(e);//通过事件元对象中的data接收主线程发送过来的数据
var submitWorker = null;
if(e.data.type == 'sum'){
submitWorker = sum(e.data.num); //辅助线程处理业务
this.postMessage(submitWorker); //辅助线程通过postMessage方法向主线程提交工作
}
// this.close(); //辅助线程主动关闭线程(关闭后不再向主线程发送消息)
}
function sum(num){
var sumVal = 0;
for(var i = 0; i < num; i++){
sumVal +=i;
}
return sumVal;
}

示例代码(两个文件的代码,注意自己拆分)

2.7worker中引入其他脚本:

 importScripts('script1.js'); //可以在辅助线程脚本中通过importScripts引入其他脚本
importScripts('script1.js', 'script2.js');//并且可以同时加载多个脚本

比如可以通过脚本引入的方式来拆分上面的worker.js文件==》

 //worker.js文件
importScripts('./workerMath.js'); //通过importScripts()方法引入其他脚本文件
this.onmessage = function(e){//在辅助线程中通过onmessage事件监听主线程postMessage发送过来的消息
// console.log(e);//通过事件元对象中的data接收主线程发送过来的数据
var submitWorker = null;
if(e.data.type == 'sum'){
submitWorker = sum(e.data.num); //辅助线程处理业务
this.postMessage(submitWorker); //辅助线程通过postMessage方法向主线程提交工作
}
// this.close(); //辅助线程主动关闭线程(关闭后不再向主线程发送消息)
} //workerMath.js文件
function sum(num){
var sumVal = 0;
for(var i = 0; i < num; i++){
sumVal +=i;
}
return sumVal;
}

三、window下的postMessage

MDN手册:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

window下的postMessage与worker中的postMessage的功能基本一致,只不过一个是实现js脚本线程之间的通信,一个是实现两个网页之间的通信。window中的postMessage主要被应用与解决主窗口与iframe子窗口中的数据传递,并且可以实现跨域通信。

示例:

 //父窗口代码
<iframe src="./winPostMessage.html"></iframe>
<script>
window.onmessage = function(e){
console.log(e);
console.log(e.data.name);//他乡踏雪
}
</script> //子窗口代码
<script>
window.parent.postMessage({name:"他乡踏雪"},'http://localhost/')
</script>

postMessage语法:

otherWindow.postMessage(message, targetOrigin, [transfer]);

otherWindow:窗口引用,比如window.parent、window.iframes[n];

message:需要传递的数据,不能使用function;

targetOrigin:可以使用URL(如示例中,窗口协议、主机地址、端口必须一致),也可以直接使用窗口对象模型的引用,比如示例中参数也可以使用window.parent。

[transfer]:(暂时还不了解其如何使用)

onmessage事件

window.addEventListener("message", receiveMessage, false);

message除了示例中的data接收postMessage传递的数,还有origin携带了传递数据的窗口的URL,以及source携带的传递数据的窗口对象模型。

HTML5之worker开启JS多线程模式及window.postMessage跨域的更多相关文章

  1. [转]js中几种实用的跨域方法原理详解

    转自:js中几种实用的跨域方法原理详解 - 无双 - 博客园 // // 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同 ...

  2. JS window.name跨域封装

    JS window.name 跨域封装 function CrossDomainName(target, agent, callback, security) { if (typeof target ...

  3. JS、JQuery和ExtJs的跨域处理

    1.什么是跨域?跨域,JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a. ...

  4. Vue.js——基于$.ajax实现数据的跨域增删查改

    概述 之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是local的.在实际的应用中,几乎90%的数据是来源于服务端的,前端和服务端之间的数据交互一般是通过ajax ...

  5. js中几种实用的跨域方法原理详解(转)

    今天研究js跨域问题的时候发现一篇好博,非常详细地讲解了js几种跨域方法的原理,特分享一下. 原博地址:http://www.cnblogs.com/2050/p/3191744.html 下面正文开 ...

  6. js中几种实用的跨域方法原理详解

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  7. js中几种实用的跨域方法原理详解【转】

    源地址:http://www.cnblogs.com/2050/p/3191744.html 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通 ...

  8. Vue.js——基于$.ajax实现数据的跨域增删查改

    转自:https://www.cnblogs.com/keepfool/p/5648674.html 概述 之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是loc ...

  9. 【转】js中几种实用的跨域方法原理详解

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

随机推荐

  1. Pycharm 常用快捷键大全

    Pycharm 常用快捷键 常用快捷键 快捷键 功能 Ctrl + Q 快速查看文档 Ctrl + F1 显示错误描述或警告信息 Ctrl + / 行注释(可选中多行) Ctrl + Alt + L ...

  2. 第三方软件 vnc提权

    通过读取注册表十进制数 将得出的十进制数去掉第一个数其他转换成16进制 破解16进制数得到密码 vncx.exe -W 回车 输入16进制数 连接vnc 读取 vncx4.exe -w 8个数 自动破 ...

  3. xshell rz commend not found

    sudo apt-get install lrzsz 上传rz 下载sz

  4. (一) kinect概述

    Kinect可以进行身体节点定位,姿势定位,人脸识别等功能,在此先做简单介绍,后续主要介绍插件的应用,毕竟自己开发识别过程太消耗时间. (注1:Kinect官方虽然提供了Unity的APi,但是方便起 ...

  5. Spring中@Resource注解报错

    描述:Spring框架中,@Resource注解报错,在书写时没有自动提示 解决方法:因为maven配置文件的pom.xml文件中缺少javax.annotation的依赖,在pom.项目路中加入依赖 ...

  6. 2018.8.15 python中的冒泡法排序

    # 给出一个纯数字列表. 请对列表进行排序. # 思路: # 1.完成a和b的数据交换. 例如, a = 10, b = 24 交换之后, a = 24, b = 10 # 2.循环列表. 判断a[i ...

  7. oracle 特殊符号替换删除处理

    1 获取ascii码 select ascii('特殊字符') from dual 2 替换 update table set testfield= replace(testfield,chr(asc ...

  8. Net Framework,Net Core 和 Net Standard 区别

    前几天我在一个群里看到有关这方面的讨论,最后感觉讨论的不是很清晰,有幸的是我们的项目去年就开始迁移NetCore的调研了,我个人多多少少也是有过这方面的研究.下面我将说一下我自己对着三个的认识如果有不 ...

  9. SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列

    分享一道今天的面试题:SQL语句实现:数据库中有A B C三列,当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列 第一种:使用case when...then...else ...

  10. 【XSY2131】【BZOJ1857】【SCOI2010】传送带

    Description 题目描述: 在一个二维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.小y在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动 ...