HTML5 WebWorkers实验

分享于 

24分钟阅读

Web开发

  繁體

目录

简介

这篇文章是关于什么的? 我以前从未做过一些不同的事情,即编写自己的插件插件,并使用HTML5插件来完成。

对于那些从未听说过的人来说,它实际上是一个JavaScript库。 下面是 jQuery 网站关于 jQuery插件的内容:

是一个快速而简洁的JavaScript库,它简化了HTML文档的遍历。事件处理。动画和AJAX交互,以便快速。 jQuery的设计改变了你编写JavaScript的方式。

-- http://jQuery.com/ 13/07/2011

你可以在 站点上阅读自己的文档,但是我将在下面的部分中详细介绍这个问题。

HTML5 WebWorker 本质上是通过JavaScript创建的线程;如果你是. NET 类型的chap,请考虑 System.Threading.Tasks.Task。 他们简单地在专用线程中执行工作单元。 稍后我们将进一步了解。

那么这两种情况如何在本文中一起使用? 很明显我需要用一些。 这就是我所提出的场景,这就是本文所做的。

如果希望将插件插入到单个元素中,那么我想创建一个插件插件,其中插件插件将接受一个 array 搜索术语。 对于每个搜索术语,将产生新的HTML5 WebWorker,用于对匹配该搜索项的图像进行 AJAX ( ) 搜索。 HTML5完成后,HTML5 WebWorker 调用回到插件,此时会创建一个图像墙。

简单来说,这就是本文代码所做的。 我们将在 below的部分中详细讨论这个问题。

编写一个jQuery插件

我在介绍中说,我想创建自己的插件。jQuery网站链接中,这是一个很好的文档过程,它可以在jQuery站点上找到:http://docs.jquery.com/Plugins/Authoring

我的插件没有实现网站上的所有建议。 以下是它所实现的功能的列表:

  • 上下文
  • 维护 Chainability
  • 默认值和选项

要了解这些含义,请参考 jQuery 网站链接: http://docs.jquery.com/Plugins/Authoring

网络worker:基本思想

HTML5的WebWorker 是相当新的,我想它们还没有广泛使用。 那么 behind的基本思想是什么? 显然,WebWorker 是一个在新线程上执行的工作单元。 是,在浏览器中创建新线程的能力。

主机与WebWorker之间的通信

主机代码( 创建 WebWorker的代码) 与实际 WebWorker 之间的通信是通过一个 PostMessage 类似的API和 WebWorker 公开的两个事件处理程序实现的。

下面是一些典型代码在宿主代码中的外观,注意我们如何创建一个新的WebWorker 并挂接它的两个事件:

  • onMessage,与 workerResultReceiver 函数钩子
  • onError,与 workerErrorReceiver 函数钩子

这个工作人员是使用 PostMessage API开始的,这就是所有消息是如何从工作人员处理的。

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// code in WebWorkwer hosting code//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++var worker = new Worker("scripts/FlickrWorkerSearch.js");
worker.onmessage = workerResultReceiver;
worker.onerror = workerErrorReceiver;
worker.postMessage({ 'cmd': 'start', 'msg': settings.searchWords[i] });function workerResultReceiver(e) {
 //so something with the workers datavar result = e.Data;
}function workerErrorReceiver(e) {
 console.log("there was a problem with the WebWorker within" + e);
}

这就是一些典型的WebWorker的样子:

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// code in WebWorkwer JavaScript file//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++self.addEventListener('message', function (e) {
 var data = e.data;
 switch (data.cmd) {
 case'start':
 postMessage("The worker says hello");
 break;
 case'stop':
 self.close(); // Terminates the worker.break;
 default:
 self.postMessage('Unknown command: ' + data.msg);
 };
}, false);

这个简单的例子简单地将一个字符串发送回主机,说 "says hello"。

工作单位

关于 WebWorker的一个工作单位是一个单一的JavaScript文件,它在构造时传递给 WebWorker,如下所示:

var worker = new Worker("scripts/FlickrWorkerSearch.js");

我们将在本文后面看到一个典型的workerJavaScript文件。

导入其他脚本

你可以使用类似于 below 所示的行导入主 WebWorker 中的其他JavaScript文件:

ImportScripts("scripts/SomeJavaScriptFile.js");

注意,你导入的JavaScript文件必须收费 以任何方式对DOM进行 touch。

警告区域

本节概述了在使用 WebWorker 时必须小心的一些领域。

无DOM访问

WebWorker 无法看到 DOM,因此将无法导入任何访问DOM的脚本,比如 在 WebWorker 中有额外的相关内容,但在中使用规则是很令人遗憾的,但规则是我认为的。

我最初认为可以使用 WebWorker 主机中的DOM来避免这个规则,并通过消息将某些对象传递给 WebWorker

一般规则是,WebWorker的消息必须是基本类型,如 array。字符串和它的他简单类型。

无线程锁定基元

好,我们可以运行线程,但不幸的是,我们没有线程对象来确保线程的安全访问。 真是个大疏忽。 它的意思是,主机内的WebWorker 及它的相关消息处理程序必须非常容易被包含,而且不访问任何共享数据结构。 当我意识到这是一个很聪明的问题,然后我将移动到本地,然后将移动到 WebWorker 中,然后再将它的移动到服务器上。

演示应用程序的工作原理

这些小节应概述演示应用的工作原理。

如何运行演示

本演示是一个VS2010解决方案,如果你没有使用 VS2010,就不用担心,只要打开 Windows Explorer 并找到文件" Index.html";是的,我需要你使用特定的浏览器。

浏览器支持

WebWorker ( s ) 由以下浏览器支持:

BrowserWebWorker支持选项
Chromev3或者 上面
Firefoxv3.5或者 上面
IEv9或者 上面
Opera10.6 或者 上面
Safari4 或者 上面

从 table 上面 中可以看出,对 WebWorker ( s ) 有很好的支持。 虽然本文不是真正的关心 跨浏览器 兼容性,但是没有花任何时间担心这一点。

我的原因如下:

  • 我想写关于 WebWorker ( s ),而不是如何让事情在浏览器中工作
  • 我只是没有足够的时间来处理这个问题
  • 我觉得这篇文章展示了 behind 使用 WebWorker ( s )的关键概念,这就是我所要做

因这里,我所知道的唯一一个浏览器是我最常用的一个网站编码,它是 Firefox ( v3.5或者 上面 )。 其他浏览器不工作的原因是免费图像库jQuery插件plug我不喜欢不同大小的图片返回到它的屏幕。 Firefox 似乎处理得很好,但 Chrome 并没有。 我是 WebWorker的,但是我们的重点是( s ) 没有修改其他图片库的,所以很抱歉,但是它是这样的方式。

HTML部分

请参阅 JavaScript file: Index.html

大部分HTML是从免费可用的图像库jQuery插件中获取的,这篇文章使用。 我所改变的唯一东西是包含我的附加JavaScript文件,并通过使用我自己的自定义jQuery插件来创建 DIV class="container" 元素的动态内容,我们将在后面讨论它。

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html><head><title>Experimenting With HTML5 WebWorkers</title><metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"/><metaname="description"content="Simple Jquery/Html5 
 WebWorkers demo to build image wall based on WebWorker Flickr search"/><metaname="keywords"content="jquery, html5, full screen, webworker, flickr"/><linkrel="stylesheet"href="css/style.css"type="text/css"media="screen"/><scripttype="text/javascript"src="scripts/jquery-1.6.2.min.js"></script><scripttype="text/javascript"src="scripts/jquery.easing.1.3.js"></script><scripttype="text/javascript"src="scripts/FlickrWall.js"></script><scripttype="text/javascript"src="scripts/FullPageImageGallery.js"></script></head><body><divid="webWorkAvailability"style="display :none;"><p>WEB WORKERS ARE NOT AVAILABLE</p></div><divid="fp_gallery"class="fp_gallery"><imgsrc="images/1.jpg"alt=""class="fp_preview"style="display: none;"/><divclass="fp_overlay"></div><divid="fp_loading"class="fp_loading"></div><divid="fp_next"class="fp_next"></div><divid="fp_prev"class="fp_prev"></div><divid="outer_container"><divid="thumbScroller"><divclass="container"></div></div></div><divid="fp_thumbtoggle"class="fp_thumbtoggle">View Thumbs</div></div><div></div></body></html>

基本上,这个部分通过使用中的插件动态更新,接下来我们将讨论这个。

<divclass="container"></div>

我说,大部分HTML是从免费可用的图像库插件中获取的,这篇文章使用的是。

部分自定义jQuery插件

请参阅 JavaScript file: FlickrWall.js

我写的搜索。 对于每个衍生的WebWorker,我定制插件插件将连接到新生成的中的onMessage()/onError 事件。WebWorker 完成时,WebWorker 调用返回到插件,此时会创建一个映像墙。

//------------------------------------------------------------------------//// This is a simple jQuery plugin that can be applied to a single element, // where the jQuery plugin would accept an array of search terms. // For each of the search terms a new Html5 WebWorker is spawned that will // do a Ajax flickr search for images that match that search term. // When the Html5 WebWorker completes, the Html5 WebWorker calls back into the // jQuery plugin, at which point an image wall is created.////------------------------------------------------------------------------(function ($) {
 $.fn.FlickrImageWall = function (options) {
 var wwsAreOk = false;
 var workersCompleted = 0;
 var src = "";
 var workerArray = new Array();
 var imagesSoFar = 0;
 var maxImages = 15;
 //Check for WebWorker availabilityif (Supports_web_workers()) {
 $(".webWorkAvailability").hide();
 wwsAreOk = true;
 } //Assume these setting values, unless new values are//supplied by the caller of this pluginvar settings = {
 'searchWords': ['dog', 'cat', 'shark']
 };
 //The is the call back from the WebWorker that is called//when the worker sends a message back to this hosting jQuery plugin//via the PostMessage APIfunction workerResultReceiver(e) {
 //Each worker must have its only local data,//cant modified unsafe global fields, as they are not thread safe.var workerImages = new Array();
 var jsonData = $.parseJSON(e.data);
 var src;
 for (var i = 0; i <5; i++) {
 src = "http://farm" + jsonData.photos.photo[i].farm + 
 ".static.flickr.com/" + jsonData.photos.photo[i].server + 
 "/" + jsonData.photos.photo[i].id + "_" + 
 jsonData.photos.photo[i].secret + "_b.jpg";
 workerImages.push(src);
 }
 PopulateWall(workerImages);
 //check to see if all the web workers have completed yet, and if stop all//workers by sending a new stop message//Pretty sure the access to imagesSoFar is not thread safe, but had no choice imagesSoFar = imagesSoFar + 1;
 if (imagesSoFar == workerArray.length) {
 for (var j = 0; j <workerArray.length; j++) {
 workerArray[j].postMessage({ 'cmd': 'stop', 'msg': null });
 }
 }
 }
 //The is the call back from the WebWorker that is called//when the worker sends a error message backfunction workerErrorReceiver(e) {
 console.log("there was a problem with the WebWorker" + e);
 }
 //The jQuery meat, this is what will be run against the selected//element set that this jQuery plugin is applied toreturnthis.each(function () {
 if (options) {
 $.extend(settings, options);
 } //allows chaining of jQuery pluginsvar $this = $(this);
 //if webworkers are supportedif (wwsAreOk) {
 //for each keyword, need to start a new web worker off that will search Flickrfor (i = 0; i <settings.searchWords.length; i++) {
 var worker = new Worker("scripts/FlickrWorkerSearch.js");
 worker.onmessage = workerResultReceiver;
 worker.onerror = workerErrorReceiver;
 worker.postMessage({ 'cmd': 'start', 'msg': settings.searchWords[i] });
 workerArray.push(worker);
 }
 }
 });
 //populate the wall by building up dynamic content based on the Ajax fetch Flickr//data. Finally make a call to the ImageGallery//jQuery plugin, via the CreateWall() functionfunction PopulateWall(images) {
 var fullcontent = "";
 for (var j = 0; j <5; j++) {
 var imagName = images[j];
 var fullstring = "<div class="content"><div><a" + 
 " href="#"><img src="" + 
 imagName + "" alt="" + imagName + 
 "" class="thumb"/></a></div></div>";
 fullcontent = fullcontent + fullstring;
 }
 $(".container").append(fullcontent);
 CreateWall();
 }
 //checks for WebWorker supportfunction Supports_web_workers() {
 return!!window.Worker;
 }
 };
})(jQuery);
$(document).ready(function () {
 //hook up FlickrImageWall jQuery plugin to the single//element that will receive the dynamic images being //added to it $(".container").FlickrImageWall({ 'searchWords': ['bikini', 'tatoo','water']
 });
});

在本文中,我将指出对 CreateWall() 调用的调用将调用第三方插件插件,本文将在映像库部分中讨论这里插件。

WebWorker部分

请参阅 JavaScript file: FlickrWorkerSearch.js

你现在已经知道,必须使用标准的JavaScript创建 WebWorker ( s )。 你现在也知道 WebWorker 不能触摸 DOM。 我已经指出我的问题域规定每个 WebWorker 都会针对 Flickr API执行AJAX请求。 - 怎么做的- 我们只需要用手工的AJAX电话。

下面是 WebWorker JavaScript文件 " flickrworkersearch.js"的完整代码,在创建新的WebWorker ( s ) plug在" flickrwall.js"中使用plug来执行搜索。

//Does the Ajax flickr search based on a given url and then//either posts the Ajax response or null using the PostMessage APIfunction GetData(url) {
 try {
 var xhr = new XMLHttpRequest();
 xhr.open('GET', url, false);
 xhr.setRequestHeader("Content-Type", 
 "application/x-www-form-urlencoded");
 xhr.onreadystatechange = function () {
 if (xhr.readyState == 4) {
 if (xhr.status == 200) {
 postMessage(xhr.responseText);
 }
 }
 };
 xhr.send(null);
 } catch (e) {
 postMessage(null);
 }
}//Adds a listener to the message event//This is the main message pump for the PostMessage API for the WebWorker,//this deals with all the different message types that the worker/host can use//to communicateself.addEventListener('message', function (e) {
 var data = e.data;
 switch (data.cmd) {
 case'start':
 var url = "http://api.flickr.com/services/rest/?method=flickr.photos.search" + 
 "&api_key=FLICKR_API_KEY&tags=" + data.msg +
 "&safe_search=1&per_page=20&format=json&nojsoncallback=1";
 GetData(url);
 break;
 case'stop':
 self.close(); // Terminates the worker.break;
 default:
 self.postMessage('Unknown command: ' + data.msg);
 };
}, false);
请注意

我已经很好地留下了 to,但请不要复制或者更改代码,或者使用to来取消 Flickr。 基本上,请 play。

图像库部分

请参见 JavaScript file: FullPageImageGallery.js 和 jquery.easing.1.3.js

我的演示中可能是最漂亮的部分,我可以不相信这一点,这只是许多免费的jQuery镜像库 Plug-Ins,它可以在互联网上使用。

原始源可用: 这个插件插件插入( 请参见 "fullpageimagegallery。js" ),它还使用了一个 jQuery easing,它是 "。easing。1.3。js"文件。

由于 WebWorker ( s ) 本质上是一个执行线程,所以我有一定的计时问题,而图像库的设计者显然没有考虑到这一点。 这导致我考虑了图像库代码,允许在接收到我自己的jQuery插件插件中的WebWorker 消息时调用该代码库。 这些变化很小,大部分与本文无关。 但是,为了实现图像库的目标,我必须提出一种动态操作DOM的方法。 不过,我必须做一些DOM操作,以使用这个 jQuery插件插件来获得动态墙,这与本文的范围无关。

尽管这是我选择这个特殊图片库插件的原因,但是它确实非常酷。

但等待浏览器的古怪

然而这个免费插件插件有一个问题,因为它假设所有图像都是一定大小的,并且它们应该是正方形的。 Firefox 似乎处理得很好,但其他浏览器的( 如 Chrome ) 没有。 这篇文章主要关注的是 WebWorker ( s ) 没有修改其他图片库的,这是一个很好的方式,但是它是一种方式。

无论如何,除了使用 WebWorker ( s ) AJAX请求返回的图片外,它还使用了动态创建的内容,使用鼠标向右滚动,然后单击一个图像( 点击下面的图片获得更大的图像)。

一旦点击了图像,它就会扩展到全屏,用户可以使用左/右按钮滚动到全屏图像。 这显示为 below ( 单击图像 below 以获得更大的图像):

总之,我对这个免费的 jQuery插件插件非常满意。

说实话,我认为微软可以从基于 jquery/社区的贡献中获得大量的知识。 想象一下人们是否可以像使用jQuery那样扩展 wpf/silverlight,并把这些东西放在那里。 我将使用动画插件中插入了jQuery插件插件,这又依赖于另一个免费可用的 jQuery插件动画插件,该插件可以在一个浏览器中。

我们可以搜索( 我经常是)/wpf控件,或者我们很容易就找到了 10 -50人下载的东西,或者我们只需要等待微软已经安装好的东西。 NET(x)。

相比之下,当你搜索类似jQuery的图像库时,有数百个字母可以从。 它只是基于更多的社区,因为它并不是因为扩展而非常关闭,所以很明显。

然而,随着任何打开,你最终看起来很好,但最终被测试,粗糙和普遍无法使用。

我个人,我喜欢互联网,所以我愿意寻找宝石。

结论

我知道,我不知道我的网络社区捐赠,并且实际上没有变化。 我看到HTML5将变得非常流行,但在我看来,有一些非常笨重的事情需要修复。

我们现在已经对额外线程( 比如线程安全) 和线程安全机制都有支持,但是我们现在几乎不知道如何使用原生的JavaScript机制,甚至是大多数语言的大多数语言都是这样。

我知道这里没有任何允许从 WebWorker 访问DOM的想法。 最好是允许它,但是必须与线程关联,它的中某些线程关联对象可以用于 WebWorker。 Windows 一直使用这种模型,Java令人惊讶地容忍线程关联。 i"无 DOM" JavaScript interaction,但是在 WebWorker 中,JavaScript交互是相当有限制的,因为它提供了很多非常有用的东西,比如做AJAX调用,解析 JSON,所有类型的东西。

总之,ranting足够了,希望你喜欢这篇文章。


WEB  EXP  Html5  webwork  webworkers  
相关文章