UDN-企业互联网技术人气社区

板块导航

浏览  : 558
回复  : 2

[原生js] Web Worker JavaScript多线程编程(二)

[复制链接]
独领风骚的头像 楼主
发表于 2017-1-4 16:10:27 | 显示全部楼层 |阅读模式
  接上篇

  上篇中提到有两种Web Worker:专用线程dedicated web worker,以及共享线程shared web worker。不过主要讲了专用线程dedicated web worker,并未提及共享线程shared web worker。那么这一篇文章继上一篇讲讲共享线程shared web worker。

  shared web worker:运行的是更为普遍性的代码,可以为多个页面服务。它可以被与之相关联的多个页面访问,只有当所有关联的的页面都关闭的时候,该Shared web worker才会结束。

  注意:如果要使共享进程可以连接到多个不同的页面,这些页面必须属于相同的域(相同的协议,主机以及端口);

  如何创建shared web worker

  创建shared web worker与创建dedicated web worker方法类似,调用SharedWorker()构造函数,指定一个要在 worker 线程内运行的脚本的 uri。

  下面的代码展示了如何通过SharedWorker()构造函数来创建一个共享进程对象。
  1. var myWorker = new SharedWorker("worker.js");
复制代码

  与dedicated web worker不同的是,shared web worker访问worker通过sharedworker.port属性创建了一个messageport对象,该对象可以用来进行通信和对共享进程进行控制。当使用addEventListener监听message事件时,端口需要手动启动,利用其start()方法,采用onmessage()则不用。
  1. myWorker.port.start();
复制代码

  端口开启后,使用port.postmessage()向SharedWorker发送消息,使用port.onmessage监听事件接收SharedWorker传递的消息,代码演示如下:
  1. first.onchange = function() {
  2.     myWorker.port.postMessage([first.value,second.value]);
  3.     console.log('Message posted to worker');
  4.   }

  5.   second.onchange = function() {
  6.     myWorker.port.postMessage([first.value,second.value]);
  7.     console.log('Message posted to worker');
  8.   }

  9.   myWorker.port.onmessage = function(e) {
  10.     result1.textContent = e.data;
  11.     console.log('Message received from worker');
  12.   }
复制代码

  在SharedWorker中,使用onconnect事件监听SharedWorker的所有页面连接在同一端口,同样用port.onmessage与页面通信接收消息,用port.postMessage向页面发回处理后的数据。
  1. onconnect = function(e) {
  2.     var port = e.ports[0];

  3.     port.addEventListener('message', function(e) {
  4.       var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
  5.       port.postMessage(workerResult);
  6.     });

  7.     port.start(); // 使用 addEventListener 监听message时需要. onmessage 则不需要
  8. }
复制代码

  使用onmessage监听事件则代码如下:
  1. onconnect = function(e) {
  2.   var port = e.ports[0];
  3.   port.onmessage(function (e) {
  4.     var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
  5.     port.postMessage(workerResult);
  6.   })
  7. };
复制代码

  注意:SharedWorker本身就是继承自Worker,所以与Worker一样受同样的限制,关于限制在Web Worker JavaScript多线程编程(一)中有介绍,在Worker的作用域中额外增添了applicationCache应用缓存(不过已经从web标准中删除),另一个就是name,在使用构造函数创建SharedWorker对象时的一个可选参数。
  1. var myWorker = new SharedWorker("worker.js","workerName");
复制代码

  这样在worker的全局作用域中可访问name,在上例代码中值为"workerName"。

  下面上一个两个html页面共享一个SharedWorker的完整简单例子:

  index1.html
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="utf-8">
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6.     <meta name="viewport" content="width=device-width">
  7.     <title>Shared Workers basic example</title>
  8.     <link rel="stylesheet" href="style.css">
  9.     <!--[if lt IE 9]>
  10.     <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  11.     <![endif]-->
  12. </head>
  13. <body>
  14. <h1>Shared<br>Workers<br>basic<br>example</h1>
  15. <div class="controls" tabindex="0">
  16.     <form>
  17.         <div>
  18.             <label for="number1">Multiply number 1: </label>
  19.             <input type="text" id="number1" value="0">
  20.         </div>
  21.         <div>
  22.             <label for="number2">Multiply number 2: </label>
  23.             <input type="text" id="number2" value="0">
  24.         </div>
  25.     </form>
  26.     <p class="result1">Result: 0</p>
  27.     <p><a href="index2.html" target="_blank">Go to second worker page</a></p>
  28. </div>
  29. </body>
  30. <script src="index1.js"></script>
  31. </html>
复制代码

  index1.js
  1. var first = document.querySelector('#number1'),
  2.     second = document.querySelector('#number2'),
  3.     result1 = document.querySelector('.result1');
  4. if (!!window.SharedWorker) {
  5.   var myWorker = new SharedWorker("worker.js",'sw1_');
  6.   first.oninput = function() {
  7.     myWorker.port.postMessage([first.value, second.value]);
  8.     console.log('Message posted to worker');
  9.   };
  10.   second.oninput = function() {
  11.     myWorker.port.postMessage([first.value, second.value]);
  12.     console.log('Message posted to worker');
  13.   };
  14.   myWorker.port.onmessage = function(e) {
  15.     result1.textContent = e.data;
  16.     console.log('Message received from worker');
  17.   };
  18. }
复制代码

  index2.html
  1. <!DOCTYPE html>
  2. <html>
  3.   <head>
  4.     <meta charset="utf-8">
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6.     <meta name="viewport" content="width=device-width">
  7.     <title>Shared Workers basic example</title>
  8.     <link rel="stylesheet" href="style.css">
  9.     <!--[if lt IE 9]>
  10.       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  11.     <![endif]-->
  12.   </head>
  13.   <body>
  14.     <h1>Shared<br>Workers<br>basic<br>example</h1>
  15.     <div class="controls" tabindex="0">
  16.     <form>
  17.       <div>
  18.         <label for="number3">Square number: </label>   
  19.         <input type="text" id="number3" value="0">
  20.       </div>
  21.     </form>
  22.     <p class="result2">Result: 0</p>
  23.     </div>
  24.   </body>
  25.   <script src="index2.js"></script>
  26. </html>
复制代码

  index2.js
  1. var squareNumber = document.querySelector('#number3'),
  2.     result2 = document.querySelector('.result2');
  3. if (!!window.SharedWorker) {
  4.   var myWorker = new SharedWorker("worker.js",'sw2_');
  5.   squareNumber.oninput = function() {
  6.     myWorker.port.postMessage([squareNumber.value, squareNumber.value]);
  7.     console.log('Message posted to worker');
  8.   };
  9.   myWorker.port.onmessage = function(e) {
  10.     result2.textContent = e.data;
  11.     console.log('Message received from worker');
  12.   }
  13. }
复制代码

  worker.js
  1. onconnect = function(e) {
  2.   var port = e.ports[0];
  3.   port.onmessage = function(e) {
  4.     var workerResult = name + 'Result: ' + (e.data[0] * e.data[1]);
  5.     port.postMessage(workerResult);
  6.   };
  7. };
复制代码

  style.css
  1. html {
  2.   background-color: #7D2663;
  3.   font-family: sans-serif;
  4. }

  5. h1 {
  6.   margin: 0;
  7.   font-size: 15vw;
  8.   letter-spacing: -0.2rem;
  9.   position: absolute;
  10.   top: 0;
  11.   z-index: -1;
  12. }

  13. p {
  14.   margin: 0 0 1rem 0;
  15. }

  16. .controls {
  17.   padding: 4vw;
  18.   width: 75%;
  19.   margin: 3vw auto;
  20.   background-color: rgba(255, 255, 255, 0.7);
  21.   border: 5px solid black;
  22.   opacity: 0.3;
  23.   transition: 1s all;
  24. }

  25. .controls:hover, .controls:focus {
  26.   opacity: 1;
  27. }

  28. .controls label, .controls p, .controls input {
  29.   font-size: 3vw;
  30. }

  31. .controls div {
  32.   padding-bottom: 1rem;
  33. }
复制代码

相关帖子

发表于 2017-1-4 16:10:58 | 显示全部楼层
js是要逆天的节奏js虽然不错,但是天生也是有缺陷,局限性。。。
使用道具 举报

回复

发表于 2017-1-4 16:10:58 | 显示全部楼层
JavaScript依赖于浏览器本身,与操作环境无关,只要计算机能运行浏览器,并支持JavaScript的浏览器,就可正确执行,从而实现了“编写一次,走遍天下”的梦想。
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部