前言

今天这篇内容主要讲述HTML 5 Web Worker(一种支持前端js多线程的技术)。

工作线程(Web Worker)

web worker介绍

W3C 在 HTML5 的规范中提出了工作线程(Web Worker)的概念,工作线程允许开发人员编写能够长时间运行而不被用户所中断的后台程序, 去执行事务或者逻辑,并同时保证页面对用户的及时响应。
工作线程的出现使得在 Web 页面中进行多线程编程成为可能。众所周知,传统页面中(HTML5 之前)的 JavaScript 的运行都是以单线程的方式工作的,虽然有多种方式实现了对多线程的模拟(例如:JavaScript 中的 setinterval 方法,setTimeout 方法等),但是在本质上程序的运行仍然是由 JavaScript 引擎以单线程调度的方式进行的。在 HTML5 中引入的工作线程使得浏览器端的 JavaScript 引擎可以并发地执行 JavaScript 代码,从而实现了对浏览器端多线程编程的良好支持。

Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。

Web Worker使用

Web Worker 可以分为两种不同线程类型,一个是专用线程 Dedicated Worker,一个是共享线程 Shared Worker。两种类型的线程各有不同的用途。下面仅仅对专用工作线程做简要描述。
Web worker的运行原理和两种线程的详细说明请查看这里

  • 创建外部javascript文件。

    它是专用线程的执行文件,即复杂的运算都在这里执行,onmessage接收主线程发送来的消息(参数),并将运行结果postMessage回主线程。

  • 在创建 web worker 对象之前,请检测用户的浏览器是否支持它。
if(typeof(Worker)!=="undefined")
  • 主线程中创建专用线程

    在创建专用线程的时候,需要给 Worker 的构造函数提供一个指向 JavaScript 文件资源的 URL,这也是创建专用线程时 Worker 构造函数所需要的唯一参数。当这个构造函数被调用之后,一个工作线程的实例便会被创建出来。下面是创建专用线程代码示例:

var worker = new Worker(jsrefurl);
  • 主线程接收专用线程发来的消息
worker.onmessage = function (event) { ... };
  • 主线程向专用线程发送消息
worker.postMessage();
  • 终止 Web Worker

    当我们创建 web worker 对象后,它会继续监听消息(即使在外部脚本完成之后)直到其被终止为止。
    如需终止 web worker,并释放浏览器/计算机资源,请使用 terminate() 方法:

worker.terminate();

示例

下面我们使用一个示例说明上述过程。

新建外部web worker 的js文件,命名为webworker.js

onmessage = function (event) {
var msg = event.data;
for (var i = 0 ; i < msg; i++) {
if (!!console && i % 500 == 0) {
console.info(i);
}
}
var d = new Date();
postMessage(d);
}

新建主线程页面,命名为webworker.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
web worker实时时间:<div id="workerTime"></div>
<br />
主线程获取当前时间:<div id="curTime"></div>
<button onclick="mainthread()">主线程获取时间</button>
<script>
var interval;
if (typeof Worker != undefined) {
var worker = new Worker("webworker1.js");
worker.onmessage = function (event)
{
document.getElementById("workerTime").textContent = event.data;
}
interval = setInterval('worker.postMessage("1000000")', 1000);
} function mainthread() {
document.getElementById("curTime").textContent = new Date();
}
function stop() {
clearInterval(interval);
       worker.terminate();
}
setTimeout(stop, 60000);//60秒之后清理interval
</script>
</body>
</html>

代码很简单,只是为了说明webworker线程不会阻塞主线程(即实现前端多线程)。

示例中我们将webworker线程设置interval不断发起请求,使用一个循环在模仿复杂操作,或者你也可以在js中加入其他操作来模拟耗时操作。

定义了一个按钮,在主线程中获取当前时间。我们可以随时点击该按钮调用主线程的方法,而其不会受到web worker线程的影响。

运行效果我就不贴图了,各园友粘贴代码即可运行查看效果。

Web Workers 和 DOM

由于 web worker 位于外部文件中,它们无法访问下列 JavaScript 对象:

  • window 对象
  • document 对象
  • parent 对象

小结

本文示例很简单,但是麻雀虽小五脏俱全。

主线程新建web worker,发送消息及接收消息,web worker 接收及反馈消息,主线程主动停止web worker线程等全都使用到了。

相信看完这个简介和示例,对web worker也有了一定掌握。

参考

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

HTML5 Web Worker的使用

HTML5简单入门系列(四)的更多相关文章

  1. HTML5简单入门系列(五)

    前言 本篇将讲述HTML5的服务器发送事件(server-sent event) Server-Sent 事件 Server-Sent 事件是单向消息传递,指的是网页自动获取来自服务器的更新. 以前的 ...

  2. HTML5简单入门系列(六)

    前言 之前几篇已经将HTML5的主要新增元素和特性简单介绍完毕,LZ一直在犹豫还要不要把其他元素也写出来,因为其实没什么东西可以写,就是自己用到时看一下就行.不过为了入门系列的完整,犹豫再三,还是决定 ...

  3. HTML5简单入门系列(八)

    前言 本篇介绍HTML5中相对复杂的一些APIs,其中的数学知识比较多.虽然如此,但是其实API使用起来还是比较方便的. 这里说明一下,只写出API相关的JS代码,因为他们都是基于一个canvas标签 ...

  4. HTML5简单入门系列(九)

    前言 上篇本来应该就是最后一篇了,但是楼主总觉得没有写上一个简单应用,不算是完整的学习系列.所以增加一篇关于动画的应用,对一个开源动画的介绍(很基础,非楼主原创). 本篇介绍一个基于Canvas的发光 ...

  5. HTML5简单入门系列(七)

    前言 本篇详细介绍canvas画布的API.说是详细介绍,也只是一些常用的API及简单实例和说明.LZ本人也还没有看完全部,下篇会介绍剩余的一些内容. 本篇的示例中,LZ加入了注释,为的是只简单介绍A ...

  6. HTML5简单入门系列(一)

    前言 随着HTML5的流行,LZ作为一个web开发者,也决定学习一下前端前沿技术. HTML5 是下一代的HTML,它将成为 HTML.XHTML 以及 HTML DOM 的新标准.它是W3C( Wo ...

  7. HTML5简单入门系列(三)

    前言 本篇介绍HTML5支持的Web存储(Web Storage)和HTML 5 应用程序缓存. 客户端存储数据介绍 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没 ...

  8. HTML5简单入门系列(二)

    前言 上篇中写到HTML5中的画布(canvas)元素,查看了canvas其他的资料,发现这个元素相关内容太多,鉴于本系列只是基础(主要是LZ也是初学),不再做太多介绍,有机会的话再单独写相关内容.说 ...

  9. 07. Web大前端时代之:HTML5+CSS3入门系列~H5 地理位置

    Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 源码:https://github.com/duniti ...

随机推荐

  1. 使用ES6进行开发的思考

    ECMAScript6已经于近日进入了RC阶段,而早在其处于社区讨论时,我就开始一直在尝试使用ES6进行开发的方案.在Babel推出后,基于ES6的开发也有了具体可执行的解决方案,无论是Build还是 ...

  2. hadoop学习之hadoop完全分布式集群安装

    注:本文的主要目的是为了记录自己的学习过程,也方便与大家做交流.转载请注明来自: http://blog.csdn.net/ab198604/article/details/8250461 要想深入的 ...

  3. 《转》ACTIONBAR-PULLTOREFRESHLIBS+沉浸式在部分手机上的布局错乱,目前知道的三星系统(TouchWiz)

    转载:http://www.cnblogs.com/wubingshenyin/p/4413672.html(原文连接) 前段时间看见ActionBar-PullToRefreshLibs用来刷新很好 ...

  4. 关appid

    https://code.google.com/p/goagent/wiki/InstallGuide 申请appid

  5. cf C. Bombs

    http://codeforces.com/contest/350/problem/C 对n个点按曼哈顿距离排序. #include <cstdio> #include <cstri ...

  6. PowerShell_零基础自学课程_1_初识PowerShell

    欢迎转载本系列文章:转载请注明出处:www.cnblogs.com/volcanol 自从微软推出.Net以来,微软旗下的windows体系就发生了很大的变化,首先是操作系统的界面的变化,例如vist ...

  7. LLVM安装

    cd ~tar -vzxf llvm-3.3.src.tar.gzmv llvm-3.3.src llvmcd llvm/tools/tar -vzxf cfe-3.3.src.tar.gzmv cf ...

  8. shell编程while

    脚本编程:    顺序结构    选择结构        if        case    循环结构        for        while        until        whil ...

  9. 《Java程序员面试笔试宝典》之volatile有什么作用

    在由Java语言编写的程序中,有时候为了提高程序的运行效率,编译器会自动对其进行优化,把经常被访问的变量缓存起来,程序在读取这个变量的时候有可能会直接从缓存(例如寄存器)中来读取这个值,而不会去内存中 ...

  10. JSTL核心标签库学习笔记

    写的很简单,不一定会有用,如果想要详细的话,建议看API啊--- 不过在这里推荐一个地址,http://www.yiibai.com/jstl/  希望对你们有帮助啊,很好的教材啊 1.<c:i ...