H5的多线程(Worker SharedWorker)使用详解

这次给大家带来H5的多线程(Worker SharedWorker)使用详解,使用H5多线程(Worker SharedWorker)的注意事项有哪些,下面就是实战案例,一起来看一下。

There is no doubt that JavaScript是没有多线程之说的,他只能一件事一件事的做,做完一件事再做下一件事,假如你的js要花一段比较长的时间做一件事的话,那么浏览器将会卡顿一段时间,不对用户的操作产生响应,这可咋办呢?谢天谢地,HTML5为我们提供了实现多线程的机制,这么好的东西,想必你早就再用了,不过没关系啊,咱们一块儿复习一下咯!

一、Worker类

  1、方法介绍

  (1)构造函数 new Worker(arg)  :参数表示你的线程要执行的代码所在的js文件,例如‘myworker.js’,构造函数当然是返回一个Worker类的实例

  (2)worker.postMessage(message):这个方法表示从主线程向子线程发送消息或者子线程向主线程发送消息,message一般是一个字符串,也可以将一个js对象转成字符串发过去

  (3)worker上还有一个message事件,当有人向这个worker实例发送消息时,该事件被触发,我们可以从他的事件对象的data属性中获得post过来的值

  可以看到Woker类的API是相当简洁的,只有两个最常用的方法,一个事件,下面我们来通过实际的例子看看。

//main.html
<!DOCTYPE html>
<html lang=en>
<head>
    <meta charset=UTF-8>
    <title>main</title>
</head>
<body>
    <p id=out></p>
    <input type=text name= id=txt>
    <button id=btn>发送</button>
    <script type=text/javascript>
        var out = document.getElementById("out");
        var btn = document.getElementById("btn");
        var txt = document.getElementById("txt");
        var worker = new Worker("thread1.js");
        btn.addEventListener("click",function(){
            var postData = txt.value;
            worker.postMessage(postData);
        },false);
        worker.addEventListener('message',function(e){
            out.innerText = e.data;
        },false);
    </script>
</body>
</html>
//thread1.js
onmessage = function(event){
    var res = event.data+"帅气!";
    postMessage(res);
}

  当我在文本框输入“大~熊”点击发送按钮就会出现如下效果

  简单分析分析,我在主线程由thead1.js创建了一个Worker的实例worker,当点击按钮时会调用他的postMessage方法,将文本框中的内容发送到thread1.js,我们的thread1.js怎么做的呢?是这样,他侦听message事件,主线程发送消息过来就触发这个事件,执行回调函数,回调函数从事件对象取得发送来的值,然后将这个值加上“帅气!”,然后在发送回去。主线程呢也侦听了worker的message事件,所以有消息过去时会触发,将消息内容显示在p中,如此就看到了上面的效果。

  或许你会将这有什么用呢?这里确实没什么用,这里我们大可以在主线程还总完成加“帅气!”的操作,因为他的复杂度为O(1)(哈哈,最近在学算法!),但是假如不是做这么简单的操作呢?这种方法的好处就是不过你的子线程做多么复杂的工作,都不会让主线程停下来,主线程改干嘛还干嘛,等到子线程把数据处理好了他直接拿过来就好了。

  陆老师将可以在子线程中在调用new Worker()创建新的子线程,我发现这样是不可以的,会报undefined错误,也就是说子线程中是不能调用Worker构造函数的,一开始以为是自己错了,后来查阅了官方文档,发现也没有相关的描述。

  下面看一个在主线程调用多个子线程的例子:

//main.html
<!DOCTYPE html>
<html lang=en>
<head>
    <meta charset=UTF-8>
    <title>main</title>
</head>
<body>
    <p id=out></p>
    <input type=text name= id=txt>
    <button id=btn>发送</button>
    <script type=text/javascript>
        var out = document.getElementById("out");
        var btn = document.getElementById("btn");
        var txt = document.getElementById("txt");
        var worker1 = new Worker("thread1.js");
        var worker2 = new Worker("thread2.js");
        btn.addEventListener("click",function(){
            var postData = txt.value;
            worker1.postMessage(postData);
        },false);
        worker1.addEventListener('message',function(e){
            worker2.postMessage(e.data);
        },false);
        worker2.addEventListener('message',function(e){
            out.innerText = e.data;
        },false);
    </script>
</body>
</html>
//thread1.js
onmessage = function(event){
    var res = event.data+"帅气!";
        postMessage(res);    
}
//thread2.js
onmessage = function(event){
    var res = event.data+"没骗你哟!";
    postMessage(res);
    close();
}

  主线程要完成一个任务需要两个线程,它创建了两个线程worker1,2,先向worker1请求,得到返回的数据后,再请求worker2,同时将worker1处理之后的数据交给worder2处理,然后拿到最终结果,显示在页面上。

  在子线程中可以引入其他的js文件然后调用,比如下边这个例子。

//main.html
<!DOCTYPE html>
<html lang=en>
<head>
    <meta charset=UTF-8>
    <title>main</title>
</head>
<body>
    <p id=out></p>
    <input type=text name= id=txt>
    <button id=btn>发送</button>
    <script type=text/javascript>
        var out = document.getElementById("out");
        var btn = document.getElementById("btn");
        var txt = document.getElementById("txt");
        var worker1 = new Worker("thread1.js");
        btn.addEventListener("click",function(){
            var postData = txt.value;
            worker1.postMessage(postData);
        },false);
        worker1.addEventListener('message',function(e){
            out.innerText = e.data;
            
        },false);
    </script>
</body>
</html>
//thread1.js
importScripts('tools.js')
onmessage = function(event){
    var res = handler(event.data);
        postMessage(res);    
}
//tools.js
function handler(data){
    return data+"加油加油!"
}

  可以看到我们的thread1.js并没有一个叫做tools.js的文件,但是它通过importScripts()导入了一个js文件,然后就可以调用里边暴露出来的方法了。

二、SharedWorker类

  SharedWorker的实质在于share,不同的线程可以共享一个线程,他们的数据也是共享的。

  直接用例子来探讨。

  使用方法一:

//main.html
<!DOCTYPE HTML>
<head>
    <title>Shared workers: demo 1</title>
</head>
<body>
    <p id=log></p>
<script>
  var worker = new SharedWorker('shared.js');
  var log = document.getElementById('log');
  worker.port.onmessage = function(e) { // note: not worker.onmessage!
    log.textContent += '\n' + e.data;
  }
</script>
</body>
</html>
//shared.js
onconnect = function(e) {
  var port = e.ports[0];
  port.postMessage('Hello World!');
}

  这是从w3c拿得一个例子,下面先看第二种方法,再做分析

<!DOCTYPE HTML>
<html>
<head>
    <title>Shared workers: demo 2</title>
</head>
<body>
<p id=log></p>
<script>
  var worker = new SharedWorker('shared.js');
  var log = document.getElementById('log');
  worker.port.addEventListener('message', function(e) {
    log.textContent += '\n' + e.data;
  }, false);
  worker.port.start(); // note: need this when using addEventListener
  worker.port.postMessage('ping');
</script>
</body>
</html>  
//shared
onconnect = function(e) {
  var port = e.ports[0];
  port.postMessage('Hello World!');
  port.onmessage = function(e) {
    port.postMessage('pong'); // not e.ports[0].postMessage!
    // e.target.postMessage('pong'); would work also
  }
}

  第一种方法中是使用事件句柄的方式将听message事件,不需要调用worker.port.start(),第二种方法是通过addEventListener()方法监听message事件,需要worker.port.start()方法激活端口。他们不同于worker,当有人和他通信时触发connect事件,然后他的message事件是绑定在messagePort对象上的,不想worker那样,你可以回头看看worker是怎么做的。

  那么sharedWorker是怎么共享数据的呢?请看下面的例子。

//main1 和main2都是这样
<!DOCTYPE HTML>
<html>
<head>
    <title>Shared workers: demo 2</title>
</head>
<body>
<p id=log></p>
<input type=text name= id=txt>
<button id=get>get</button>
<button id=set>set</button>
<script>
  var worker = new SharedWorker('shared.js');
  var get = document.getElementById('get');
  var set = document.getElementById('set');
  var txt = document.getElementById('txt');
  var log = document.getElementById('log');
  worker.port.addEventListener('message', function(e) {
    log.innerText = e.data;
  }, false);
  worker.port.start(); // note: need this when using addEventListener
  set.addEventListener('click',function(e){
      worker.port.postMessage(txt.value);
  },false);
  get.addEventListener('click',function(e){
      worker.port.postMessage('get');
  },false);
</script>
</body>
</html>
//shared
var data;
onconnect = function(e) {
  var port = e.ports[0];
  port.onmessage = function(e) {
    if(e.data=='get'){
        port.postMessage(data);
    }else{
        data=e.data;
    }
  }
}

  这里分析一波,我们在main1.html的文本框输入数据,点击set,然后在main2.html中点击get法现能够获取到我们在main1.html中设置的数据,这说明我们的sharedWorker事实上是单例的,就像java中的static类一样,不管new多少个,实际上只有一个,这样我们的不同线程就可以共享到sharedWorker中的数据了。这里把图给上,记得有篇文章没给图,然后有人给我建议了,问能不能给图。

相信看了本文案例你已经掌握了方法,更多精彩请关注云资源网其它相关文章!

推荐阅读:

怎样使用phonegap查找联系人

phonegap获取设备信息方法详解

以上就是H5的多线程(Worker SharedWorker)使用详解的详细内容,更多请关注云资源网其它相关文章!

原文链接:https://www.sudo1.com

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
9.本站默认解压密码为:www.sudo1.com
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。
本站信息来自网络收集整理,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。
我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解!

云资源网 » H5的多线程(Worker SharedWorker)使用详解

常见问题FAQ

免费下载或者VIP会员专享资源能否直接商用?
本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
提示下载完但解压或打开不了?
最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。 若排除这种情况,可在对应资源底部留言,或 联络我们.。
你们有qq群吗怎么加入?
当然有的,如果你是帝国cms、易优cms、和pbootcms系统的爱好者你可以加入我们的QQ千人交流群https://www.sudo1.com/page-qun.html。
  • 会员数(个)
  • 12310资源数(个)
  •        
  • 资源(G)
  •        
  • 今日下载
  • 1506稳定运行(天)

提供最优质的资源集合

立即查看 了解详情