H5 Web Workers API详细介绍

H5 Web Workers API详细介绍

1.简介

我们都知道JavaScript这个语言在执行的时候是采用单线程进行执行的,也就是说在同一时间只能做一件事,这也和这门语言有很大的关系,采用同步执行的方式进行运行,如果出现阻塞,那么后面的代码将不会执行,HTML5则提出了web Worker标准,表示JavaScript允许有多个线程,但是子线程完全受主线程的控制,切子线程不能操作DOM,只有主线程可以操作DOM,所以以主线程为主的单线程执行原理成了JavaScript这门语言的核心。

2.什么是Web Worker

Web Worker 是浏览器为我们提供的一个可以再浏览器后台开启一个新的线程的 API,使得运行在浏览器中的 js 有了多线程的能力。但是这并不意味这 js 本身就支持多线程.

3.检测 Web Worker 支持

在创建 web worker 之前,请检测用户的浏览器是否支持它:

if(typeof(Worker)!=="undefined")
  {
  // Yes! Web worker support!
  // Some code.....
  }
else
  {
  // Sorry! No Web Worker support..
  }

4.创建线程

在创建线程的时候需要给实例化的Worker传入唯一一个参数,指向一个javascript文件资源的url或者Blob对象(Blob对象就是一个包含有只读原始数据类文件对象),调用这个构造函数之后,一个线程就被创建了,如下:

var worker = new Worker("worker.js");
var worker = new Worker(blob);

5.线程通信

Web Worker的基本原理就是在当前的主线程中加载一个只读文件来创建一个新的线程,两个线程同时存在,且互不阻塞,并且在子线程与主线程之间提供了数据交换的接口postMessage和onmessage。来进行发送数据和接收数据。其数据格式可以为结构化数据(JSON等);
当我们创建了一个worker实例之后,我们可以通过如下两种方式来发送数据:

var worker = new Worker("worker.js");  //实例化对象

//第一种传递方式
worker.postMessage(message,taransferList);

//第二种传递方式
worker.postMessage({ 
     operation: "list_all_users", 
     //ArrayBuffer object 
     input: buffer, 
     threshold: 0.8, 
}, [buffer]);

同时我们如果需要接收某个线程传来的数据可以使用onmessage来进行接收,方法如下:

//方法一
worker.onmessage = function(event){
    var data = event.data;        //通过event.data来获取传入的参数
}

//方法二
worker.addEventListener("message",target);

下面是一段运行在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是如下:
这里写图片描述

6、Worker基本使用

上面我们已经说了创建一个新的线程、传递数据、接收数据的方法,下面再次做一个精简的回顾。

创建新的Worker
var worker = new Worker(“worker.js”)
传递参数
worker.postMessage(“text”);
接收消息
worker.onmessage = function (e) {
var message = e.data;
};
异常处理
worker.onerror = function(e){
console.log(“error at “+e.filename “:” + e.lineno + e.message)
}
结束worker
worker.terminate();
载入工具类函数
importScripts(“./utils/base64.js”,”./utils/map.js”…)
需要注意的是importScripts是同步方法,一旦importScripts方法返回就可以开始使用载入的脚本,而不需要回调函数。

7、Worker作用域

当我们创建一个新的worker时,该代码会运行在一个全新的javascript的环境中(WorkerGlobalScope)运行,是完全和创建worker的脚本隔离,这时我们可以吧创建新worker的脚本叫做主线程,而被创建的新的worker叫做子线程。

WorkerGlobalScope是worker的全局对象,所以它包含所有核心javascript全局对象拥有的属性如JSON等,window的一些属性,也拥有类似于XMLHttpRequest()等。

但是我们所开启的新的worker也就是子线程,并不支持操作页面的DOM。

8、共享线程 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://segmentfault.com/a/1190000012528806

猜你喜欢

转载自blog.csdn.net/yangyuqingabc/article/details/80489328
今日推荐