加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

HTML5之web workers_动力节点Java学院整理

发布时间:2020-03-16 11:14:07 所属栏目:MySql教程 来源:站长网
导读:副标题#e# 专用 Web Worker (Dedicated Web Worker) 提供了一个简单的方法使得 web 内容能够在后台运行脚本。一旦 worker 创建后,它可以向由它的创建者指定的事件监听函数传递消息,这样该 worker 生成的所有任务就都会接收到这些消息。worker 线程能够在
副标题[/!--empirenews.page--]

专用 Web Worker (Dedicated Web Worker) 提供了一个简单的方法使得 web 内容能够在后台运行脚本。一旦 worker 创建后,它可以向由它的创建者指定的事件监听函数传递消息,这样该 worker 生成的所有任务就都会接收到这些消息。worker 线程能够在不干扰 UI 的情况下执行任务。另外,它还能够使用XMLHttpRequest(虽然responseXML与channel 两个属性值始终是null)来执行I/O 操作。本文通过提供例子和细节补全了前面的文档。提供给 worker 的函数列出了 worker 所支持的函数。

Worker接口会生成真正的操作系统级别的线程,如果你不太小心,那么并发(concurrency)会对你的代码产生有趣的影响。然而,对于 web worker 来说,与其他线程的通信点会被很小心的控制,这意味着你很难引起并发问题。你没有办法去访问非线程安全的组件或者是 DOM,此外你还需要通过序列化对象来与线程交互特定的数据。所以你要是不费点劲儿,还真搞不出错误来。生成 worker

创建一个新的 worker 十分简单。你所要做的就是调用Worker()构造函数,指定一个要在 worker 线程内运行的脚本的 URI,如果你希望能够收到 worker 的通知,可以将 worker 的onmessage属性设置成一个特定的事件处理函数。

var myWorker = new Worker("my_task.js"); myWorker.onmessage = function (oEvent) { console.log("Called back by the worker!n"); };

或者,你也可以使用addEventListener():

var myWorker = new Worker("my_task.js"); myWorker.addEventListener("message", function (oEvent) { console.log("Called back by the worker!n"); }, false); myWorker.postMessage(""); // start the worker.

例子中的第一行创建了一个新的 worker 线程。第三行为 worker 设置了message事件的监听函数。当 worker 调用自己的postMessage() 函数时就会调用这个事件处理函数。最后,第七行启动了 worker 线程。注意: 传入Worker构造函数的参数 URI 必须遵循同源策略。目前,不同的浏览器制造商对于哪些 URI 应该遵循同源策略尚有分歧;Gecko 10.0 (Firefox 10.0 / Thunderbird 10.0 / SeaMonkey 2.7) 及后续版本允许传入 data URI,而 Internet Explorer 10 则不认为 Blob URI 对于 worker 来说是一个有效的脚本。

传递数据

在主页面与 worker 之间传递的数据是通过拷贝,而不是共享来完成的。传递给worker 的对象需要经过序列化,接下来在另一端还需要反序列化。页面与 worker不会共享同一个实例,最终的结果就是在每次通信结束时生成了数据的一个副本。大部分浏览器使用结构化拷贝来实现该特性。

在往下进行之前,出于教学的目的,让我们创建一个名为emulateMessage()的函数,它将模拟在从worker到主页面(反之亦然)的通信过程中,变量的「拷贝而非共享」行为:

function emulateMessage (vVal) { return eval("(" + JSON.stringify(vVal) + ")"); } // Tests // test #1 var example1 = new Number(3); alert(typeof example1); // object alert(typeof emulateMessage(example1)); // number // test #2 var example2 = true; alert(typeof example2); // boolean alert(typeof emulateMessage(example2)); // boolean // test #3 var example3 = new String("Hello World"); alert(typeof example3); // object alert(typeof emulateMessage(example3)); // string // test #4 var example4 = { "name": "John Smith", "age": 43 }; alert(typeof example4); // object alert(typeof emulateMessage(example4)); // object // test #5 function Animal (sType, nAge) { this.type = sType; this.age = nAge; } var example5 = new Animal("Cat", 3); alert(example5.constructor); // Animal alert(emulateMessage(example5).constructor); // Object

拷贝而并非共享的那个值称为消息。再来谈谈worker,你可以使用postMessage() 将消息传递给主线程或从主线程传送回来。message事件的data属性就包含了从 worker 传回来的数据。

example.html: (主页面):

var myWorker = new Worker("my_task.js"); myWorker.onmessage = function (oEvent) { console.log("Worker said : " + oEvent.data); }; myWorker.postMessage("ali"); my_task.js (worker): postMessage("I'm working before postMessage('ali')."); onmessage = function (oEvent) { postMessage("Hi " + oEvent.data); };

注意:通常来说,后台线程 – 包括 worker –无法操作 DOM。如果后台线程需要修改 DOM,那么它应该将消息发送给它的创建者,让创建者来完成这些操作。

如你所见,worker与主页面之间传输的消息始终是「JSON 消息」,即使它是一个原始类型的值。所以,你完全可以传输JSON数据 和/或 任何能够序列化的数据类型:

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

传递数据的例子

例子 #1: 创建一个通用的 「异步eval()」

下面这个例子介绍了,如何在 worker 内使用eval()来按顺序执行异步的任何种类的 JavaScript 代码:

// Syntax: asyncEval(code[, listener]) var asyncEval = (function () { var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D"); oParser.onmessage = function (oEvent) { if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); } delete aListeners[oEvent.data.id]; }; return function (sCode, fListener) { aListeners.push(fListener || null); oParser.postMessage({ "id": aListeners.length - 1, "code": sCode }); }; })();

示例使用:

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读