突袭HTML5之Javascript API扩展1—Web Worker异步执行及相关概述
Javascript执行机制 在HTML5之前,浏览器中JavaScript的运行都是以单线程的方式工作的,虽然有多种方式实现了对多线程的模拟(例如:Javascript 中的 setinterval 方法,setTimeout 方法等),但是在本质上程序的运行仍然是由 JavaScript 引擎以单线程调度的方式进行的。在 HTML5 中引入的工作线程使得浏览器端的 Javascript 引擎可以并发地执行 Javascript 代码,从而实现了对浏览器端多线程编程的良好支持。 Javascript中的多线程 - WebWorker HTML5 中的 Web Worker 可以分为两种不同线程类型,一个是专用线程 Dedicated Worker,一个是共享线程 Shared Worker。两种类型的线程各有不同的用途。 专用型web worker 专用型worker与创建它的脚本连接在一起,它可以与其他的worker或是浏览器组件通信,但是他不能与DOM通信。专用的含义,我想就是这个线程一次只处理一个需求。专用线程在除了IE外的各种主流浏览器中都实现了,可以放心使用。 创建线程 创建worker很简单,只要把需要在线程中执行的JavaScript文件的文件名传给构造函数就可以了。 线程通信 在主线程与子线程间进行通信,使用的是线程对象的postMessage和onmessage方法。不管是谁向谁发数据,发送发使用的都是postMessage方法,接收方都是使用onmessage方法接收数据。postMessage只有一个参数,那就是传递的数据,onmessage也只有一个参数,假设为event,则通过event.data获取收到的数据。 发送JSON数据 JSON是JS原生支持的东西,不用白不用,复杂的数据就用JSON传送吧。例如: 复制代码 代码如下: 处理错误 当线程发生错误的时候,它的onerror事件回调会被调用。所以处理错误的方式很简单,就是挂接线程实例的onerror事件。这个回调函数有一个参数error,这个参数有3个字段:message - 错误消息;filename - 发生错误的脚本文件;lineno - 发生错误的行。 销毁线程 在线程内部,使用close方法线程自己销毁自己。在线程外部的主线程中,使用线程实例的terminate方法销毁线程。 下面从一个例子看线程的基本操作: HTML代码: 复制代码 代码如下: 脚本文件fibonacci.js代码: 复制代码 代码如下: 把它们放到相同的目录,运行页面文件,查看控制台,可以看到运行的结果。 这里还有一点,在主线程中,onmessage事件可以使用另外一种方式挂接: 复制代码 代码如下: 个人觉得很麻烦,不如用onmessage直接。 使用其他脚本文件 工作线程可以使用全局方法importScripts来加载和使用其他的域内脚本文件或者类库。例如下面都是合法的使用方式: 复制代码 代码如下: 导入以后,可以直接使用这些文件中的方法。看一个网上的小例子: 复制代码 代码如下: 网上也有网友想到了利用这里的importScripts方法解决资源预加载的问题(浏览器预先加载资源,而不会对资源进行解析和执行),道理也很简单。 线程嵌套 在工作线程中还可以在创建子线程,各种操作还是一样的。 同步问题 Worker没有锁的机制,多线程的同步问题只能靠代码来解决(比如定义信号变量)。 共享型SharedWebWorker 共享型web worker主要适用于多连接并发的问题。因为要处理多连接,所以它的API与专用型worker稍微有点区别。除了这一点,共享型web worker和专用型worker一样,不能访问DOM,并且对窗体属性的访问也受到限制。共享型web worker也不能跨越通信。 页面脚本可以与共享型web worker通信,然而,与专用型web worker(使用了一个隐式的端口通信)稍微有点不同的是,通信是显式的通过使用一个端口(port)对象并附加上一个消息事件处理程序来进行的。 在收到web worker脚本的首个消息之后,共享型web worker把一个事件处理程序附加到激活的端口上。一般情况下,处理程序会运行自己的postMessage()方法来把一个消息返回给调用代码,接着端口的start()方法生成一个有效的消息进程。 看网上能找到的的唯一个例子:创建一个共享线程用于接收从不同连接发送过来的指令,然后实现自己的指令处理逻辑,指令处理完成后将结果返回到各个不同的连接用户。 HTML代码: 复制代码 代码如下:(编辑:焦作站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |