最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

HTML5多线程JavaScript解决方案WebWorker-专用Worker和共享Worker的详细代码介绍

来源:动视网 责编:小采 时间:2020-11-27 15:11:42
文档

HTML5多线程JavaScript解决方案WebWorker-专用Worker和共享Worker的详细代码介绍

HTML5多线程JavaScript解决方案WebWorker-专用Worker和共享Worker的详细代码介绍:不得不说,HTML5确实提供了大量强大的功能特性 甚至颠覆了我们之前理解的JavaScript单线程 它提供了JavaScript多线程的解决方案 这个新特性叫做Web Worker (在此之前没有多线程,setTimeout等本质仍然是单线程) 虽然是多线程编程 不过我们不用担心传统的
推荐度:
导读HTML5多线程JavaScript解决方案WebWorker-专用Worker和共享Worker的详细代码介绍:不得不说,HTML5确实提供了大量强大的功能特性 甚至颠覆了我们之前理解的JavaScript单线程 它提供了JavaScript多线程的解决方案 这个新特性叫做Web Worker (在此之前没有多线程,setTimeout等本质仍然是单线程) 虽然是多线程编程 不过我们不用担心传统的
 不得不说,HTML5确实提供了大量强大的功能特性
甚至颠覆了我们之前理解的JavaScript单线程
它提供了JavaScript多线程的解决方案
这个新特性叫做Web Worker
(在此之前没有多线程,setTimeout等本质仍然是单线程)
虽然是多线程编程
不过我们不用担心传统的多线程语言C++、Java等等遇到的多线程问题
下面我们就来看看什么是Web Worker

专用Worker

专用Worker(Dedicated Worker)是最常用的Web Worker
而且各个浏览器实现的还不错

声明

什么时候我们需要多线程呢
比如说我们需要复杂的计算、

//demo.jsfunction calculate(){
 var ret = 0; for(var i = 1; i <= 1e9; i++){
 ret += i;
 } return ret;
}var result;var start;var end;
start = +new Date();
result = calculate();
end = +new Date();
console.log(result); //500000000067109000console.log(end - start); //977

我们计算了从1加到10亿的值
让页面的渲染停了将近1秒钟
对于用户的体验来说是相当不友好的
虽然开发中不会有这么丧心病狂的计算
但是可能会遇到密集而又复杂的任务
这时我们也许会希望开辟一个独立的新线程来完成
而我们只需要关注结果值


HTML5允许我们使用Worker线程
它的工作内容需要写在一个独立的js文件中
让我们的多个程序块并发运行

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

通过这种方式来实例化一个worker
参数是js文件的路径(HTML主文件和Worker文件需要满足同源策略)
当程序运行到这里时
这个文件就会被加载到一个Worker中
浏览器就会启动一个独立线程运行该js文件

交互

我们的主线程和工作线程是基于事件的机制来进行交互的
换句话说,
它们都需要订阅事件来互相通信(onmessage事件)

//主线程
worker.addEventListener('message', function(e){
 //e.data为从worker线程得到的数据
});
worker.possMessage(...);//向worker线程发送数据
//工作线程
addEventListener('message', function(e){
 //e.data为从主线程得到的数据
});
possMessage(...);//向主线程发送数据

它们的数据绑定和数据发送时类似的
只不过在worker文件中不需要用对象调用API
这样我们刚才的复杂计算就可以让worker来做

//worker.jsfunction calculate(){
 var ret = 0; for(var i = 1; i <= 1e9; i++){
 ret += i;
 } return ret;
}
postMessage(calculate());
//demo.jsvar worker = new Worker('scripts/worker.js');
worker.addEventListener('message', function(e){
 console.log(e.data); //500000000067109000}, false);

在HTML5的Web Worker规范中
worker中还可以实例化它自己的worker(感觉没什么必要啊)
称为subworker(线程嵌套线程)
不过我测试了一下,chrome暂时还不支持subworker
但是据说Firefox支持

终止

既然我们可以创建worker
那么我们也应该可以终止worker让它停止工作
在主线程和工作线程中都可以终止
只需要在worker对象或worker的作用域中调用API
一个是我们让它结束工作
一个是它自己罢工

//主线程worker.terminate();
//工作线程close();

不过我想我们一般情况下
都会以worker对象上调用terminate方法的来终止它
这样会比较安全

环境

最开始的时候我就说了
我们不必担心传统的多线程语言遇到的多线程问题
比如说为了防止它们抢占资源而引入的…
无比复杂的锁机制
为什么呢?
因为在worker内部
我们根本就不能访问主程序的任何资源
它就是一个完全独立的线程
Web Worker有如下限制:

  • 同源策略限制

  • 不能访问页面DOM和其他资源

  • 浏览器实现程度不同

  • 不过我们可以在worker内部做这些事情:

  • 可以执行网络操作(Ajax、Web Sockets)

  • 可以使用定时器(set/clearTimeout()、set/clearInterval())

  • 访问某些重要全局变量及功能的复本(navigator、location、JSON、applicationCache)

  • 可以使用importScrips()加载额外js脚本

  • importScripts('foo.js','bar.js');importScripts('foobar.js');

    好奇的话,可以在worker内console.log(this);
    查看它的作用域内都有什么

    应用

    关于它的应用
    我们会利用Web Worker做这些事情

  • 复杂数学计算

  • 复杂数据排序

  • 数据处理(压缩、图像处理…)

  • 高流量网络通信

  • 共享Worker

    除了专用线程外还有一个共享线程Shared Worker
    可以了解一下
    刚刚我查了一下
    到目前为止,只有谷歌、火狐还有欧朋实现了这个技术


    如果我们的网站或者App可以同时加载多个tab(标签页)
    那么如果使用普通的worker我们可能会重复创造多个线程
    这必然会占用系统资源
    这时如果我们可以让App或整站的页面实例都能够共享一个worker
    那就很棒了~
    共享线程和专用线程使用方式差不多,稍微复杂一点点而已

    var worker = new SharedWorker('scripts/worker.js');

    由于共享线程需要与多个程序实例或页面链接
    所以它需要通过某种方式来了解消息的来源
    这个方式就是利用一个唯一标识符port(端口)
    这样我们刚才的例子就需要写成这个样子

    //demo.jsvar worker = new SharedWorker('scripts/worker.js');
    worker.port.addEventListener('message', function(e){
     console.log(e.data); //500000000067109000}, false);
    worker.port.start();

    在主线程中
    端口连接必须初始化
    使用API worker.port.start();

    //worker.jsfunction calculate(){
     var ret = 0; for(var i = 1; i <= 1e9; i++){
     ret += i;
     } return ret;
    }
    addEventListener('connect', function(e){
     var port = e.ports[0];
     port.start();
     port.postMessage(calculate());
    });

    在共享worker内部同样需要初始化端口连接port.start();
    除此之外,我们还需要处理额外事件onconnect
    这个事件为我们的特定连接提供了端口对象
    var port = e.ports[0];用于获取连接分配的端口


    我们的onmessage事件就可以写在onconnect事件处理函数内部

    addEventListener('connect', function(e){
     var port = e.ports[0];
     port.addEventListener('message', function(e){ ...
     port.postMessage(...); ...
     });
     port.start();
    });

    除此之外,其他的功能共享Worker和专用Worker都是一样的

    文档

    HTML5多线程JavaScript解决方案WebWorker-专用Worker和共享Worker的详细代码介绍

    HTML5多线程JavaScript解决方案WebWorker-专用Worker和共享Worker的详细代码介绍:不得不说,HTML5确实提供了大量强大的功能特性 甚至颠覆了我们之前理解的JavaScript单线程 它提供了JavaScript多线程的解决方案 这个新特性叫做Web Worker (在此之前没有多线程,setTimeout等本质仍然是单线程) 虽然是多线程编程 不过我们不用担心传统的
    推荐度:
    标签: 介绍 html5 javascript
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top