最新文章专题视频专题问答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新特性之WebWorker

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

HTML5新特性之WebWorker

HTML5新特性之WebWorker:1、概述http://www.gxlcms.com/wiki/48.html target=_blank
推荐度:
导读HTML5新特性之WebWorker:1、概述http://www.gxlcms.com/wiki/48.html target=_blank


1、概述

http://www.gxlcms.com/wiki/48.html" target="_blank">JavaScript语言采用的是单线程模型,也就是说,所有任务排成一个队列,一次只能做一件事。随着电脑计算能力的增强,这一点带来很大的不便,无法充分发挥JavaScript的潜能。龙其考虑到,File API允许JavaScript读取本地文件,就更加如此了。

Web Worker的目就,就是为JavaScript创造多线程环境,允许主线程将一些任务分配给子线程。在主线程运行的同时,子线程在后台运行,两者互不干扰。等到子线程完成计算任务,再把结果返回给主线程。因此,每一个子线程就好像一个“工人”(worker),默默地完成自己的工作。

Web Worker有以下几个特点:

  • 同域限制:子线程加载的脚本文件,必须与主线程的脚本文件在同一个域。

  • DOM限制:子线程无法读限网页的DOM对象,即document、window、parent这些对象,子线程都无法得到。(但是,navigator对象和location对象可以获得。)

  • 脚本限制:子线程无法读取网页的全局变量和函数,也不能执行alert和confirm方法,不过可以执行setInterval和setTimeout,以及使用XMLHttpRequest对象发出AJAX请求。

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

  • 使用之前,检查浏览器是否支持这个API。支持的浏览器包括 IE 10+、Firefox 3.6+、Safari 4.0+、Chrome 和 Opera 11,但是手机浏览器还不支持。

    if (window.Worker) { // 支持} else { // 不支持}

    2、新建和启动子线程

    在主线程内部,采用new命令调用Worker方法,可以新建一个子线程。

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

    Worker方法的参数是一个脚本文件,这个文件就是子线程所要完成的任务,上面代码中是work.js。由于子线程不能读取本地文件系统,所以这个脚本文件必须来自网络端。如果下载没有成功,比如出现404错误,这个子线程就会默默地失败。

    子线程新建之后,并没有启动,必需等待主线程调用postMessage方法,即发出信号之后才会启动。

    worker.postMessage('hello world');

    postMessage方法的参数,就是主线程传给子线程的信号。它即可以是一个字符串,也可以是一个对象。

    worker.postMessage({method: 'each', args: ['work']});

    3、子线程的事件监听

    在子线程内,必须有一个回调函数,监听message事件。

    //File: work.jsself.addEventListener('message', function(e) {
    
     self.postMessage('You said: ' + e.data);
    
    }, false);

    self代表子线程自身,self.addEventListener表示对子线程的message事件指定回调函数(直接指定onmessage属性的值也可以)。回调函数的参数是一个事件对象,它的data属性包含主线程发来的信号。self.postMessage则表示,子线程向主线程发送一个信号。

    根据主线程发来的不同的信号值,子线程可以调用不同的方法。

    'message', method = args = reply =);

    4、主线程的事件监听

    主线程也必须指定message事件的回调函数,监听子线程发来的信号。

    // File: main.jsworker.addEventListener('message', function(e) {
     console.log(e.data);
    }, false);

    5、错误处理

    主线程可以监听子线程是否发生错误。如果发生错误,会触发主线程的error事件。

    worker.onerror(function(e) {
     console.log(e);
    });// orworker.addEventListener('error', function(e) {
     console.log(e);
    }, false);

    6、关闭子线程

    使用完毕后,为了节省系统资源,我们必须在主线程调用terminate方法,手动关闭子线程。

    worker.terminate();

    也可以子线程内部关闭自身。

    self.close();

    7、主线程与子线程的数据通信

    主线程与子线程之间的通信内容,可以是文本,也可以是对象。需要注意的是,这种通信是拷贝关系,即是传值而不是传址,子线程对通信内容的修改,不会影响到主线程。事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给子线程,后者再将它还原。

    主线程也子线程这间也可以交换二进制数据,比如File、Blob、ArrayBuffer等对象,也可以在线程之间发送。

    但是,用拷贝方式发送二进制数据,会造成性能问题。比如,主线程向子线程发送一个500MB文件,默认情况下浏览器会生成一个原文件的拷贝。为了解决这个问题,JavaScript允许主线程把二进制数据直接转移给子线程,但是一旦转移,主线程就无法再使用这些二进制数据了,这是为了防止出现多个线程同时修改数据的麻烦局面。这种转移数据的方法,叫做Transferable Objects。

    如果要使用该方法,postMessage方法的最后一个参数必须是一个数组,用来指定前面发送的哪些值可以被转移给子线程。

    worker.postMessage(arrayBuffer, [arrayBuffer]);

    8、同页面的Web Worker

    通常情况下,子线程载入的是一个单独的JavaScript文件,但是也可以载入与主线程在同一个网页的代码。假设网页代码如下:

    <!DOCTYPE html>
     <body>
     <script id="worker" type="app/worker">
    
     addEventListener('message', function() {
     postMessage('Im reading Tech.pro');
     }, false); </script>
     </body></html>

    我们可以读取页面的script,用worker来处理。

    var blob = new Blob([document.querySelector('#workere').textContent]);

    这里需要把代码当作二进制数据读取,所以使用Blob接口。然后,这个二进制对象转为URL,再通过这个URL创建worker。

    var url = window.URL.createObjectURL(blob);var worker = new Worker(url);

    部署事件监听代码。

    worker.addEventListener('message', function(e) {
     console.log(e.data);
    }, false);

    最后启动worker。

    worker.postMessage('');

    整个页面的代码如下:

    <!DOCTYPE html>
     <body>
     <script id="worker" type="app/worker">
    
     addEventListener('message', function() {
     postMessage('Work done!');
     }, false); </script>
    
     <script>
     (function() { 
     var blob = new Blob([document.querySelector('#worker').textContent]); 
     var url = window.URL.createObjectURL(blob); 
     var worker = new Worker(url);
    
     worker.addEventListener('message', function(e) {
     console.log(e.data);
     }, false);
    
     worker.postMessage('');
     })(); </script>
     </body></html>

    可以看到,主线程和子线程的代码都在同一个网页上面。

    上面所讲的Web Worker都是专属于某个网页的,当该网页关闭,worker就自动结束。除此之外,还有一种共享式的Web Worker,允许多个浏览器窗口共享同一个worker,只有当所有窗口关闭,它才会结束。这种共享式的Worker用SharedWorker对象来创建,因为适用场合不多,这里就省略了。

    文档

    HTML5新特性之WebWorker

    HTML5新特性之WebWorker:1、概述http://www.gxlcms.com/wiki/48.html target=_blank
    推荐度:
    标签: html5 html 新特性
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top