Javascript执行机制
      在HTML5之前,浏览器中JavaScript的运行都是以单线程的方式工作的,虽然有多种方式实现了对多线程的模拟(例如:Javascript 中的 setinterval 方法,setTimeout 方法等),但是在本质上程序的运行仍然是由 JavaScript 引擎以单线程调度的方式进行的。在 HTML5 中引入的工作线程使得浏览器端的 Javascript 引擎可以并发地执行 Javascript 代码,从而实现了对浏览器端多线程编程的良好支持。

Javascript中的多线程 - WebWorker
      HTML5 中的 Web Worker 可以分为两种不同线程类型,一个是专用线程 Dedicated Worker,一个是共享线程 Shared Worker。两种类型的线程各有不同的用途。

专用型web worker

  专用型worker与创建它的脚本连接在一起,它可以与其他的worker或是浏览器组件通信,但是他不能与DOM通信。专用的含义,就是这个线程一次只处理一个需求。专用线程在除了IE外的各种主流浏览器中都实现了,可以放心使用。
创建线程
      创建worker很简单,只要把需要在线程中执行的JavaScript文件的文件名传给构造函数就可以了。

线程通信
      在主线程与子线程间进行通信,使用的是线程对象的postMessage和onmessage方法。不管是谁向谁发数据,发送发使用的都是postMessage方法,接收方都是使用onmessage方法接收数据。postMessage只有一个参数,那就是传递的数据,onmessage也只有一个参数,假设为event,则通过event.data获取收到的数据。

发送JSON数据
      JSON是JS原生支持的东西,不用白不用,复杂的数据就用JSON传送吧。例如:

postMessage({'cmd': 'init', 'timestamp': Date.now()});

处理错误
      当线程发生错误的时候,它的onerror事件回调会被调用。所以处理错误的方式很简单,就是挂接线程实例的onerror事件。这个回调函数有一个参数error,这个参数有3个字段:message - 错误消息;filename - 发生错误的脚本文件;lineno - 发生错误的行。

销毁线程
      在线程内部,使用close方法线程自己销毁自己。在线程外部的主线程中,使用线程实例的terminate方法销毁线程。

HTML代码:

<script type="text/javascript">
  onload = function(){
      var worker = new Worker('fibonacci.js');  
      worker.onmessage = function(event) {
        console.log("Result:" + event.data);
      };
      worker.onerror = function(error) {
        console.log("Error:" + error.message);
      };
      worker.postMessage(40);
  }  
  </script>
脚本文件fibonacci.js代码:
//fibonacci.js
var fibonacci = function(n) {
    return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2);
};
onmessage = function(event) {
    var n = parseInt(event.data, 10);
    postMessage(fibonacci(n));
};

把它们放到相同的目录,运行页面文件,查看控制台,可以看到运行的结果。
这里还有一点,在主线程中,onmessage事件可以使用另外一种方式挂接:

worker.addEventListener('message', function(event) {
   console.log("Result:" + event.data);
}, false);

个人觉得很麻烦,不如用onmessage直接。

使用其他脚本文件
      工作线程可以使用全局方法importScripts来加载和使用其他的域内脚本文件或者类库。例如下面都是合法的使用方式:

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

导入以后,可以直接使用这些文件中的方法。看一个网上的小例子:


 importScripts('math_utilities.js'); 
 
 onmessage = function (event) 
 { 
   var first = event.data.first; 
   var second = event.data.second; 
   calculate(first,second); 
 }; 
 
 function calculate(first,second) { 
    //do the calculation work 
   var common_divisor=divisor(first,second); 
   var common_multiple=multiple(first,second); 
   postMessage("Work done! " + 
      "The least common multiple is " + common_divisor  +
" and the greatest common divisor is "+common_multiple); 
 } 

网上也有网友想到了利用这里的importScripts方法解决资源预加载的问题(浏览器预先加载资源,而不会对资源进行解析和执行),道理也很简单。

线程嵌套
      在工作线程中还可以在创建子线程,各种操作还是一样的。

同步问题
      Worker没有锁的机制,多线程的同步问题只能靠代码来解决(比如定义信号变量)。

共享型SharedWebWorker
  共享型web worker主要适用于多连接并发的问题。因为要处理多连接,所以它的API与专用型worker稍微有点区别。除了这一点,共享型web worker和专用型worker一样,不能访问DOM,并且对窗体属性的访问也受到限制。共享型web worker也不能跨越通信。
  页面脚本可以与共享型web worker通信,然而,与专用型web worker(使用了一个隐式的端口通信)稍微有点不同的是,通信是显式的通过使用一个端口(port)对象并附加上一个消息事件处理程序来进行的。

  在收到web worker脚本的首个消息之后,共享型web worker把一个事件处理程序附加到激活的端口上。一般情况下,处理程序会运行自己的postMessage()方法来把一个消息返回给调用代码,接着端口的start()方法生成一个有效的消息进程。
      看网上能找到的的唯一个例子:创建一个共享线程用于接收从不同连接发送过来的指令,然后实现自己的指令处理逻辑,指令处理完成后将结果返回到各个不同的连接用户。
HTML代码:

<script> 
  var worker = new SharedWorker('sharedworker.js'); 
  var log = document.getElementByIdx_x_x_x_x('response_from_worker'); 
  worker.port.addEventListener('message', function(e) { 
  //log the response data in web page 
  log.textContent =e.data; 
  }, false); 
  worker.port.start(); 
  worker.port.postMessage('ping from user web page..'); 
  
  //following method will send user input to sharedworker 
  function postMessageToSharedWorker(input) 
  { 
  //define a json object to construct the request 
  var instructions={instruction:input.value}; 
  worker.port.postMessage(instructions); 
  } 
  </script> 
 

脚本文件代码:

// 创建一个共享线程用于接收从不同连接发送过来的指令,指令处理完成后将结果返回到各个不同的连接用户。
 var connect_number = 0; 
 
 onconnect = function(e) { 
  connect_number =connect_number+ 1; 
  //get the first port here 
  var port = e.ports[0]; 
  port.postMessage('A new connection! The current connection number is ' 
  + connect_number); 
  port.onmessage = function(e) { 
   //get instructions from requester 
   var instruction=e.data.instruction; 
   var results=execute_instruction(instruction); 
    port.postMessage('Request: '+instruction+' Response '+results 
      +' from shared worker...'); 
  }; 
 }; 
 function execute_instruction(instruction) 
 { 
 var result_value; 
 //implement your logic here 
 //execute the instruction... 
 return result_value;
 } 

在上面的共享线程例子中,在主页面即各个用户连接页面构造出一个共享线程对象,然后定义了一个方法 postMessageToSharedWorker 向共享线程发送来之用户的指令。同时,在共享线程的实现代码片段中定义 connect_number 用来记录连接到这个共享线程的总数。之后,用 onconnect 事件处理器接受来自不同用户的连接,解析它们传递过来的指令。最后,定义一个了方法 execute_instruction 用于执行用户的指令,指令执行完成后将结果返回给各个用户。

这里我们并没有跟前面的例子一样使用到了工作线程的 onmessage 事件处理器,而是使用了另外一种方式 addEventListener。实际上,前面已经说过,这两种的实现原理基本一致,只是在这里有些稍微的差别,如果使用到了 addEventListener 来接受来自共享线程的消息,那么就要先使用 worker.port.start() 方法来启动这个端口。之后就可以像工作线程的使用方式一样正常的接收和发送消息。

线程中能做的事
1.能使用setTimeout(), clearTimeout(), setInterval(),clearInterval()等函数。
2.能使用navigator对象。
3.能使用XMLHttpRequest来发送请求。
4.可以在线程中使用Web Storage。

5.线程中可以用self获取本线程的作用域。

线程中不能做的事
1.线程中是不能使用除navigator外的DOM/BOM对象,例如window,document(想要操作的话只能发送消息给worker创建者,通过回调函数操作)。
2.线程中不能使用主线程中的变量和函数。
3.线程中不能使用有"挂起"效果的操作命令,例如alert等。
4.线程中不能跨域加载JS。

线程也是需要消耗资源的,而且使用线程也会带来一定的复杂性,所以如果没有充足的理由来使用额外的线程的话,那么就不要用它。

转载于:https://www.cnblogs.com/zhwl/p/4667470.html

HTML5之Javascript多线程相关推荐

  1. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

  2. JavaScript多线程编程介绍

    综述:两种JavaScript多线程编程的方法,在以后的具有大量的数据计算的业务场景下可能会使用到 1.背景介绍 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成, ...

  3. javaScript 多线程并行编程 施工中~

    关键词:javascript 单线程本质,html5,worker,nodejs 封面P站画师ID:12191398 查看全文 http://www.taodudu.cc/news/show-4981 ...

  4. 10个奇幻的HTML5和Javascript效果

    导读:10款令人惊奇的HTML5和javascript效果.回到几年前,这些效果是根本不可能实现,只能用flash做,但是现在,已经很轻松的就可以实现了. Breathing Galaxies 使用键 ...

  5. Javascript 多线程编程​的前世今生

    作者:jolamjiang,腾讯 WXG 前端开发工程师 一篇关于 Web Worker.SharedArrayBuffer.Atomics 的文章. 为什么要多线程编程 大家看到文章的标题<J ...

  6. html5 --- 使用javascript脚本控制媒体播放

    H5中的标签(<audio-/> 和 <video-/>)对于JS中的HTMLAudioElement对象和HTMLVideoElement对象 对象有以下几个方法: play ...

  7. 如何使用HTML5,JavaScript和Bootstrap构建自定义文件上传器

    by Prashant Yadav 通过Prashant Yadav 如何使用HTML5,JavaScript和Bootstrap构建自定义文件上传器 (How to build a custom f ...

  8. js调用vlc_如何使用HTML5或JavaScript查看RTSP流,而不使用Real Player插件上的VLC插件等插件?...

    The idea is to develop a cross-platform, standalone application that could play a video, streamed ov ...

  9. 《HTML5和JavaScript Web应用开发》——第 2 章 移动Web 2.1移动优先

    本节书摘来自异步社区<HTML5和JavaScript Web应用开发>一书中的第2章,第2.1节,作者:[美]Wesley Hales著,更多章节内容可以访问云栖社区"异步社区 ...

最新文章

  1. NeurIPS | 2019 机器学习领域最新十篇论文,来自谷歌、Facebook、普林斯顿大学、斯坦福大学等团队的最新研究成果...
  2. oracle exp语句 按日期命名,Windows平台下Oracle数据库exp全备脚本,根据时间保留备份数及自动上备份至FTP...
  3. vuex重置所有state(可定制)
  4. [css] 如何解决IE6浮动时产生双倍边距的BUG?
  5. Java并发编程实战 第14章 构建自定义的同步工具
  6. Visual Studio2010重新安装后,冲突问题
  7. 10个有关String的面试问题
  8. OpenShift 4 - 多云管理(1) - 安装 RHACM、导入已有集群、配置观察功能
  9. python,可变参数
  10. SpringBoot集成elasticsearch 总结
  11. 从法外狂徒张三卖房引起的代理模式
  12. 零基础学前端之SEO 基础知识学习--SEO优化学习教程【学习笔记】
  13. 湖北省2019.3全国计算机等级考试,湖北2019年3月全国计算机等级考试报名系统
  14. 从用户个体的角度,谈微信群吱口令红包
  15. JS:打字游戏_键盘事件监听
  16. 360网站卫士SQL注入绕过案例一个
  17. 王慧文广发英雄帖:组队拥抱新时代 打造中国OpenAI
  18. 英语——不定词(二)
  19. 中国芥酸酰胺市场现状研究分析与发展前景预测报告(2022)
  20. Amazon S3 Tools 简介及使用

热门文章

  1. 如何网络推广分析新站上线后网站不收录的原因有哪些?
  2. 龙岗网络推广解析有关网站SEO排名上去了,但没实际性点击的问题
  3. 西安网络推广教大家如何正确解决处理网站死链
  4. 网络推广外包中目标用户习惯对企业网站设计与开发有重要影响
  5. dba用什么工具连接mysql_DBA必备的15款MySQL管理工具
  6. 网络请求可以返回数据的网站_实例解析|Python加解密VIP网站反爬请求头实现数据爬取...
  7. rs485调试软件_5种RS485切换方向的方法及优劣势分析
  8. linux cp命令逻辑,Linux-CP命令
  9. yum安装php和apache先装哪个,yum如何安装apache与php
  10. cdt规约报文用程序解析_DNS协议(报文解析)