在博主的前些文章Promise的前世今生和妙用技巧JavaScript单线程和浏览器事件循环简述中都曾提到了HTML5 Web Worker这一个概念。在JavaScript单线程和浏览器事件循环简述中讲述了JavaScript出于界面元素访问安全的考虑,所以JavaScript运行时一直是被实现为单线程执行的;这也意味着我们应该尽量的避免在JavaScript中执行较长耗时的操作(如大量for循环的对象diff等)或者是长时间I/O阻塞的任务,特别是对于CPU计算密集型的操作。

例如在JavaScript中尝试计算像fibonacci这类计算密集型的操作,就会导致整个页面体验被blocked。HTML5 Web Worker的出现让我们在不阻塞当前JavaScript线程的情况下,在当前的JavaScript执行线程中可利用Worker这个类新开辟一个额外的线程来加载和运行特定的JavaScript文件,这个新的线程和JavaScript的主线程之间并不会互相影响和阻塞执行的;并且在Web Worker中提供这个新线程和JavaScript主线程之间数据交换的接口:postMessage和onmessage事件。它和C# WinForm中的BackgroundWorker很类似。

Web Worker实现fibonacci计算

利用HTML5 Web Worker实现fibonacci可像如下所示(plnkr在线demo):

fibonacci.js Worker JavaScript文件:

(function() {
var fibonacci = function(n) {
return n < 2 ? 1 : (fibonacci(n - 1) + fibonacci(n - 2));
}; onmessage = function(event) {
postMessage({
input: event.data,
result: fibonacci(event.data)
});
}; })();

在fibonacci.js中利用onmessage方法来监听主线程发送的fibonacci计算请求,和利用postMessage返回计算的结果到请求线程。

script.js 主线程JavaScript文件:

$(function() {
var $input = $('#input'),
$btn = $('#btn'),
$result = $('#result'),
worker = new Worker('fibonacci.js'),
timeKey = function(val) {
return 'fibonacci(' + val + ')';
}; worker.onmessage = function(event) {
console.timeEnd(timeKey(event.data.input));
$result.text(event.data.result);
}; $btn.on('click', function() {
var val = parseInt($input.val(), 10);
if (val) {
console.time(timeKey(val));
$result.text('?')
worker.postMessage(val);
}
});
});

在这个JavaScript文件中,利用new Worker('fibonacci.js')方式来创建Web Worker对象,并利用Worker对象上的postMessage方法发送请求计算请求,以及利用Worker对象的onmessage的方法接受Worker线程的返回结果,并显示在UI界面上。同时我们也利用了console最新的time API来统计计算所花费的时间。

其显示效果如下:

在console中打印的时间信息为:

fibonacci(10): 1.022ms
fibonacci(20): 1.384ms
fibonacci(30): 22.065ms
fibonacci(40): 1744.352ms
fibonacci(50): 202140.027ms

从这里时间输出可以看出,在计算n为40的fibonacci 开始时间开始急速的加长,在UI中返回结果的时间也逐渐变长;但是在Web Worker后台计算的时候,它并不会阻塞我们的UI界面的其他交互。

Web Worker总结

Web Worker在这类耗时计算密集型操作中,显得特别实用。在Web Worker中我们可以实现:

  1. 可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信;
  2. 可以在worker中通过importScripts(url)加载另外的脚本文件;
  3. 可以使用 setTimeout(),clearTimeout(),setInterval(),clearInterval();
  4. 可以使用XMLHttpRequest来发送请求,以及访问navigator的部分属性。

但是它也存在一些来自浏览器安全沙盒的限制:

  1. 不能加载跨域的JavaScript文件;
  2. 如文件开始所说,考虑到JavaScript操作DOM的安全性问题,在Web Worker中不能访问界面中的DOM信息,对于DOM的访问操作都必须委托给JavaScript主线程来操作;因此HTML5 Web Worker的出现的出现,并没有改变JavaScript单线程执行的这个事实;
  3. 还有就是Web Worker的浏览器兼容性问题。它的浏览器兼容性图如下:

更多关于Web Worker的资料,请参考https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

JavaScript多线程之HTML5 Web Worker的更多相关文章

  1. 【转向Javascript系列】深入理解Web Worker

    本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/11/deep-in-web-worker/ 上一篇文章<从setTimeout说事件循 ...

  2. 深入HTML5 Web Worker应用实践:多线程编程

    HTML5 中工作线程(Web Worker)简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越多崭新的特性和功能.它不但强化了 Web 系统或网页的表现性能 ...

  3. 深入理解javascript异步编程障眼法&&h5 web worker实现多线程

    0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 1 2 3 4 ...

  4. 深入 HTML5 Web Worker 应用实践:多线程编程

    深入 HTML5 Web Worker 应用实践:多线程编程 HTML5 中工作线程(Web Worker)简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越 ...

  5. html5 web worker学习笔记(记一)

    (吐槽:浏览器js终于进入多线程时代!) 以前利用setTimeout.setInterval等方式的多线程,是伪多线程,本质上是一种在单线程中进行队列执行的方式.自从html5 web worker ...

  6. HTML5 Web Worker的使用

    Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker Web Wo ...

  7. 深入理解JS异步编程四(HTML5 Web Worker)

    >Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker We ...

  8. HTML5 Web Worker简单使用

    Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker Web Wo ...

  9. 一个简单的HTML5 Web Worker 多线程与线程池应用

    笔者最近对项目进行优化,顺带就改了些东西,先把请求方式优化了,使用到了web worker.发现目前还没有太多对web worker实际使用进行介绍使用的文章,大多是一些API类的讲解,除了涉及到一些 ...

随机推荐

  1. CSS3 background-image背景图片相关介绍

    这里将会介绍如何通过background-image设置背景图片,以及背景图片的平铺.拉伸.偏移.设置大小等操作. 1. 背景图片样式分类 CSS中设置元素背景图片及其背景图片样式的属性主要以下几个: ...

  2. 我为什么要写LeetCode的博客?

    # 增强学习成果 有一个研究成果,在学习中传授他人知识和讨论是最高效的做法,而看书则是最低效的做法(具体研究成果没找到地址).我写LeetCode博客主要目的是增强学习成果.当然,我也想出名,然而不知 ...

  3. .NET平台开源项目速览(17)FluentConsole让你的控制台酷起来

    从该系列的第一篇文章 .NET平台开源项目速览(1)SharpConfig配置文件读写组件 开始,不知不觉已经到第17篇了.每一次我们都是介绍一个小巧甚至微不足道的.NET平台的开源软件,或者学习,或 ...

  4. 再部署一个 instance 和 Local Network - 每天5分钟玩转 OpenStack(131)

    上一节部署了 cirros-vm1 到 first_local_net,今天我们将再部署 cirros-vm2 到同一网络,并创建 second_local_net. 连接第二个 instance 到 ...

  5. Yeoman 官网教学案例:使用 Yeoman 构建 WebApp

    STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...

  6. 用神奇的currentColor制作简洁的颜色动画效果

    先上一个兼容性总结图:老版本ie可以直接用复杂方法了,套用某表情包的话:  2016年了,做前端你还考虑兼容IE6?你这简直是自暴自弃! 好了,知道了兼容性,我们可以放心的使用了. 在CSS3中扩展了 ...

  7. Java—恶心的java.lang.NumberFormatException解决

    项目中要把十六进制字符串转化为十进制, 用到了到了Integer.parseInt(str1.trim(), 16):这个是不是后抛出java.lang.NumberFormatException异常 ...

  8. App解读

    一直不懂别人口中说的原生开发.混合式开发.今天突然看了一篇文章讲解的是什么叫做原生App?移动 Web App?混合APP?分享给大家. 原生App是专门针对某一类移动设备而生的,它们都是直接安装到设 ...

  9. XAMARIN ANDROID 二维码扫描示例

    现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile  做一个简单的 Android 条码扫描示 ...

  10. mono for android学习过程系列教程(2)

    接着上一讲继续开始写,今天介绍的是安卓的基本组成结构. 在大多数情况下,MONO FOR ANDROID的命名空间和Android的命名空间 是互相映射的.有时候需要大小写,非字母数字字符的用法以及名 ...