html5 之 web worker
当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。
web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。
可以通过一些事件来触发 web worker 在后台运行,然后将运行的结果能过postMessage(data),将data消息发回页面。完成有点类似于AJAX的异步处理流程
if(typeof(Worker)!=="undefined")//检查浏览器是否支持 { if(typeof(w)=="undefined") { w=new Worker("js/workers.js"); w.postMessage(nums);//向后台发送数据 } w.onmessage = function (event) { alert(event.data); }; }
通过w.onmessage=function(event){} 来获取通信数据。
w.addEventListener('message', function(event){ alert(event.data); }
或者
w.onmessage = function (event) { alert(event.data); };
通过w.terminate();来终止web worker;
其它方法:
close:停止 Worker 的行为。
importScripts
Workers 线程会动态加载外部脚本,调用该方法则会冻结 Worker 的线程,直到动态加载脚本完毕或脚本执行完毕(具体视浏览器而定),该方法可以方便开发者在 Web Workers 的脚本文件中载入其他脚本文件(例如 JavaScript 代码很长,需要分开几个文件编写时该方法便十分有用)。由于 Web Workers 是在独立线程中工作,它无法访问 document 对象,即无法访问外部资源,因此需要用该方法载入外部脚本。
另外关于 importScript 还有以下两点需要注意:
importScripts 支持同时加载多个脚本,只需在每个参数中填写一个 JavaScript 文件,如:importScripts('a.js', 'b.js', 'c.js');
只要 HTTP 连接数足够,使用 importScripts 同时加载多个脚本时均为并行加载。但执行这些脚本是按照参数顺序进行的,如上面的例子,则按照 a.js , b.js , c.js 的顺序执行各脚本(即使 b.js 脚本比 a.js 脚本先加载完毕,也会等待 a.js 加载完毕并且执行 a.js 后才会执行 b.js )
onerror
worker.onerror = function(event){ event.message // 具体的错误信息 event.lineno // 在 demo_workers.js 中导致错误发生的语句的所在行号 event.filename // 返回发生错误的文件的完整 URL };
Subworker
Worker 支持在一个 Worker 内部创建 Worker ,称为 Subworker 。这个 Worker 必须与父 Workers 同源,它的 URL 是根据父 Worker 的 URL 确定的,而不是依据它自己的页面 URL ,这样导致了以下两个需要注意的地方:
Subworker 不能跨域
内部 Worker 引用资源必须使用相对 URL(相对于创建父 Worker 的页面,即上例中的 index.html)。
Shared Worker
开发者也可以创建一个被多个页面或连接使用的 Worker ,称为 Shared Worker(共享 Worker ),可以用于页面之间的共享通讯,它的工作方式与普通 Worker 稍有不同,目前主流浏览器对其支持都很不完善,因此这里不作详细介绍。
PS:
1、js/workers.js,是主在后台运行的代码,它有postMessage(data)
2、测试的js和html文件都需要发布到站点才可以正常访问,否则会提示这个错误:
Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///E:/work/study/webapp/workers.js' cannot be accessed from origin 'null'.
3、浏览器支持
Chrome 3+ , Firefox 3.5+ , Safari 4+ 和 Opera 10.6+