HTML5新特性之Web Workers
来源:互联网 发布:线切割绘图编程步骤 编辑:程序博客网 时间:2024/06/14 02:36
我们知道浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,从而造成用户体验的大打折扣。Web Workers作为HTML5新特性之一,为浏览器端JavaScript开创了一种新的运行模式,使之能够在另外的线程中创建新的运行环境,以便使JavaScript能够在后台做一些费时的处理。下面我们就来详细介绍一下Web Workers方面的知识。
Web Workers可以通过加载一个脚本文件,进而创建一个独立的工作线程,在主线程之外运行。工作线程的创建比较简单,代码如下:
var worker = new Worker('js/worker.js');如代码所示,我们只需将含有工作线程的代码文件路径作为参数传入到Worker构造函数中,即可创建一个工作线程,使其能够在后台执行。需要注意的是,脚本的加载有同源策略的限制,所以必须指定与主线程同源的文件。
在创建完工作线程后,我们就可以在主线程中与工作线程通信了。主线程中通过postMessage方法向工作线程发送消息,也可以通过捕获worker实例的message事件来接收来自工作线程的消息。需要注意的是,在postMessage方法中,我们可以相对自由的传递各种类型的数据,但是像document等BOM对象是无法被传递的。下面就让我们来看看主线程中是如何和工作线程交互的:
//message sendingworker.postMessage({name: 'Scott'});//message receivingworker.onmessage = function(event) {var data = event.data;//to do}同样的,在工作线程中我们也可以通过postMessage和onmessage方法来发送和接收数据,下面是工作线程文件worker.js中的代码:
//message sendingself.postMessage({name: 'Worker'});//message receivingself.onmessage = function(event) {var data = event.data;//to do}
在某些情况下,我们不得不中断工作线程的运行,主线程中我们可以调用worker实例的terminate方法,在工作线程中我们也可以调用close方法中断自身,代码如下:
//interrupt a work thread in main threadworker.terminate();//interrupt work thread it selfself.close();以上介绍了Web Workers的基本用法,接下来我们来以一个实例说明它在实际项目中是如何应用的。
我们经常会加入一些技术群组里探讨技术,广交朋友,如果群组成员太多,查看起来就不太方便,为此我们打算给这个群组加一个搜索的功能,根据关键字搜索与成员信息匹配的数据,就像下面图中所示:
在这个案例中,群组成员信息预先加载到了客户端,搜索功能也是在客户端完成的,假如数据非常多,一个简单的搜索可能就会在用户体验上造成不小的折扣,我们打算用Web Workers来实现这个操作。现在来看一下示例项目的基本目录结构:
我们可以看到,在js目录中有个worker.js文件,用于放置工作线程的逻辑代码,此文件在运行时被主线程加载,我们稍后会详细讲解。现在我们先看一下主页面的基本结构:
<html><head><title>Web Worker</title><link rel="stylesheet" type="text/css" href="css/main.css"></head><body><div id="searching"><input id="keywords" type="text" placeholder="type in to start searching"><button id="search-button" onclick="search();">search</button><div id="members"><!-- <div class="member"><img src="img/icon.png"><div class="info"><p>John Li</p><p>Java programming, Python language</p></div><a class="add">+Add</a></div> --><!-- the search results will be here --></div></div><script type="text/javascript" src="js/jquery.js"></script><script type="text/javascript" src="js/main.js"></script></body></html>看起来很简单,一个搜索框和搜索按钮,下面是搜索结果显示区域。为了使其运行起来,我们还需要main.js的配合,代码如下:
//a simple group member data examplevar groupMembers = [{id: 101,name: 'John Li',skills: 'Java programming, Python language, MySQL'},{id: 102,name: 'Lisa Wang',skills: 'HTML, JavaScript, CSS, Node.js'},{id: 103,name: 'Tom Wang',skills: 'JavaScript, CSS, HTML5'},{id: 104,name: 'Andy Zhang',skills: 'PHP language, JavaScript programming, CSS'}/*a large number of data*/];//loading the worker.js to instantiate a Worker objectvar worker = new Worker('js/worker.js');//receive message from work thread, and then render the result dataworker.onmessage = function(e) {renderGroupMembers(e.data.results);};function search() {var keywords = $('#keywords').val().trim();//post a message to work threadworker.postMessage({groupMembers: groupMembers,keywords: keywords});}function renderGroupMembers(members) {var html = '';members.forEach(function(member) {var resultHtml = '<div class="member">' + '<img class="icon" src="img/icon.png">' + '<div class="info">' + '<p>' + member.name + '</p>' + '<p>' + member.skills + '</p>' + '</div>' + '<a class="add">+Add</a>' + '</div>';html += resultHtml;});$('#members').html(html);}renderGroupMembers(groupMembers);在这段代码中,我们首先会加载worker.js,实例化一个Worker对象,然后捕获message事件,进而将搜索结果显示到相应区域。而search函数负责监听搜索按钮的点击事件,然后向工作线程发送带有群组数据和关键字的消息,将搜索任务交给工作线程。
最后,我们开看看worker.js是如何运行的:
//receive the message from main threadself.onmessage = function(e) {var groupMembers = e.data.groupMembers;var keywords = e.data.keywords;var results = searchByKeywords(groupMembers, keywords);//post the result message to main threadself.postMessage({results: results});};//it may be quite complicated in real applicationfunction searchByKeywords(groupMembers, keywords) {var results = [];keywords = keywords.toLowerCase();groupMembers.forEach(function(member) {var nameMatched = member.name.toLowerCase().indexOf(keywords) > -1;var skillsMatched = member.skills.toLowerCase().indexOf(keywords) > -1;if (nameMatched || skillsMatched) {results.push(member);}});return results;}从上面的代码中可以看到,首先我们会捕获工作线程的message事件,接收群组数据和关键字,然后调用搜索函数,最后将搜索结果发送回主线程,完成这次的搜索任务。
以上就是Web Workers的介绍,在实际开发中,可能面临很多复杂的操作需要在前端完成,我们都可以考虑用Web Workers实现,将复杂操作交给工作线程,进而减少主线程的阻塞,在用户体验上一定会有显著的提升。
- HTML5新特性之Web Workers
- HTML5之Web Workers
- Html5之web workers多线程
- Web Workers---html5 Web Workers
- html5学习笔记之九(web workers)
- Html5开发之Web Workers概要
- HTML5新特性之Web存储
- HTML5新特性之Web Notifications
- HTML5 Web Workers
- HTML5 web workers
- html5 使用 Web Workers
- HTML5 --Web Workers
- HTML5 Web Workers
- HTML5 Web Workers
- HTML5 Web Workers
- HTML5-Web Workers
- 25、html5 Web Workers
- HTML5--Web Workers
- 工具-监测页面有哪些事件的小工具 Visual Event
- ListView的优化
- HTML5 New Feature Series: WebSocket
- MSSQL2008数据同步浅析二(安装篇)
- redhat/centos修改yum源
- HTML5新特性之Web Workers
- Qt 知识的总结
- cocos2d-x 2.2.6
- 正则表达式
- Monkey测试简介
- 开启Mac自带apache和PHP开发环境
- 数据库之聚合函数与分组
- Android-init.c
- HTML5 New Feature Series: Web Workers