doubleyong
管理员
管理员
  • 最后登录2021-07-30
  • 发帖数1019
  • 最爱沙发
  • 喜欢达人
  • 原创写手
  • 社区居民
  • 忠实会员
阅读:1587回复:0

【转】web worker 详细介绍

楼主#
更多 发布于:2020-03-15 20:48

1、简介

我们都知道javaScript是采用单线程执行的,同一时间只能做一件事,如果采用同步执行的,出现阻塞那么后面的代码将不会执行,HTML5则提出了Web Worker标准,表示js允许多线程,但是子线程完全受主线程控制并且不能操作dom,只有主线程可以操作dom,所以js本质上依然是单线程语言。
关于js的运行机制可以参考阮一峰文章JavaScript 运行机制详解:再谈Event Loop



2、web worker

web worker就是在js单线程执行的基础上开启一个子线程,进行程序处理,而不影响主线程的执行,当子线程执行完之后再回到主线程上,在这个过程中不影响主线程的执行。


2.1、创建线程

var worker = new Worker('worker.js');

其中的worker.js是一个单独的js文件,以上代码创建了一个子线程,还可以使用下面的方式


var worker = new Worker(blob);

传入的参数
  • 一个指向 js文件资源的url
  • Blob 对象,就是一个包含只读原始数据类文件对象
2.2、线程间通信

web worker的基本原理是在当前的主线程中加载一个只读文件,来创建一个新的线程,两个线程同时存在且互补阻塞,并且子线程与主线程之间提供了数据交互的接口postMessage和onmessage,来进行数据发送和接收。


2.2.1、数据发送

var worker = new Worker('worker.js'); // 第一种传递方式 worker.postMessage(message, transferList); // 第二种方式 worker.postMessage({
    operation:'list_all_users', // ArrayBuffer Object input:buffer,
    thresold:0.8,
}, [buffer]);


如果要想一个专用线程发送数据,那么我们需要使用线程中的 postMessage 方法。专用线程不仅仅支持传输二进制数据,也支持结构化的 JavaScript 数据格式。在这里有一点需要注意,为了高效地传输 ArrayBuffer 对象数据,需要在 postMessage 方法中的第二个参数中指定它。


2.2.2、数据接收
//方法一 
worker.onmessage = function(event){
 var data = event.data; //通过event.data来获取传入的参数
 }
 //方法二 
worker.addEventListener("message",target);

2.2.3、示例代码

下面是一段运行在chrome中的参数传递方式:
index.html
<!DOCTYPE html>
 <html lang="en"> 
<head> <meta charset="UTF-8"> <title>webWorker</title> </head> 
<body>
 <script> 
var worker = new Worker("worker.js");
 worker.postMessage("123456");
  worker.onmessage = function (e) {
 console.log(e.data)
 };
 </script> </body> </html>


worker.js

onmessage = function (e) { console.log(e.data);
    postMessage("2222")
};

此时我们的浏览器打印出的log是如下:



2.2.4、异常处理
worker.onerror = function(e){
    console.log("error at "+e.filename ":" + e.lineno + e.message)
}


2.2.5、结束线程

worker.terminate();

3、worker 作用域

当我们创建一个新的worker时,改代码会运行在一个全新的javascript的环境中(WorkerGlobalScope)运行,是完全和创建worker的脚本隔离,这时我们可以吧创建新worker的脚本叫做主线程,而被创建的新的worker叫做子线程。
WorkerGlobalScope是worker的全局对象,所以它包含所有核心javascript全局对象拥有的属性如JSON等,window的一些属性,也拥有类似于XMLHttpRequest()等。
但是我们所开启的新的worker也就是子线程,并不支持操作页面的DOM。


4、SharedWorker 共享线程

共享线程是为了避免线程的重复使用和销毁过程,降低了系统性能的消耗,共享线程SharedWorker可以有多个页面的线程链接。
使用SharedWorker创建共享线程,也需要提供一个javascript脚本文件的URL地址或Blob,该脚本文件中包含了我们在线程中需要执行的代码,如下:
var worker = new SharedWorker('sharedworker.js');

共享线程也使用了message事件监听线程消息,但使用SharedWorker对象的port属性与线程通信如下。

worker.port.onmessage = function(e){
 ... 
}

同时我们也可以使用SharedWorker对象的port属性向共享线程发送消息如下。

worker.port.postMessage("message");

转自:https://blog.csdn.net/ithanmang/article/details/82622420
知识需要管理,知识需要分享
游客


返回顶部

公众号

公众号