当前位置: 首页 > Web前端 > HTML5

WebWorkerAPI简介

时间:2023-04-05 16:36:16 HTML5

WebWorker可以理解为一种在后台线程中运行js的方法,可以在不阻塞用户UI界面的情况下执行js代码。WebWorker可以向创建它的JavaScript代码发送消息(worker可以依次生成新的worker,只要它运行在同一个父页面中),反之亦然可以从主线程接收消息注:worker运行在另一个全局context中,不同于当前窗口。因此,如果使用window快捷方式获取当前全局作用域,会在一个Worker中返回错误(直接访问需要访问的属性!例如:console而不是window.console)。worker中可用的函数和接口WebWorker中的一些方法和属性是不能访问的,比如BOM的一些API和DOM相关的一些API,localStorage,SessionStorage等,但是大部分window对象是可以访问的,比如:Websocket,XMLHttpRequest(也不能跨域?)ConsoleApi、Array、Date、Math、String等,也就是说所有涉及到页面操作和页面的对象都无法访问。它的应用场景是代替主线程执行和消费页面性能代码。下面是WebWorker允许访问的方法和属性的列表。常用worker的主要wroker类型有专用worker(只在单个脚本中使用)和sharedworker(多个脚本同时使用);DedicatedWorkerGlobalScope和SharedWorkerGlobalScope对象代表各自的Context使用为了更好的错误处理控制和向后兼容性,需要做一些兼容性检测if(window.Worker){somecodes...}接收指定URL脚本的对象(脚本必须遵守同源策略,否则会报错)varmyWorker=newWorker('worker.js');数据传递主线程和工作线程都使用postMessage()方法发送各自的消息,并使用onmessage事件处理器来响应消息(消息包含在Message事件的data属性中),数据在此过程中不共享但复制。在主线程中使用时,onmessage和postMessage()必须挂在worker对象上,在worker中使用则不挂。原因是,在worker内部,worker实际上是全局范围。/*Mainthread*///SenddatatoworkermyWorker.postMessage('canyouhearme?');//监听和接收来自worker线程的数据myWorker.onmessage=function(e){console.log(e.data);//'我可以听见你!'}/*工作线程*///监听并从主线程接收数据onmessage=function(e){console.log(e.data);//'你能听到我说话吗?'//发送数据给workere.data&&postMessage('Icanhearyou!');}Terminateworker如果你需要立即从主线程终止一个正在运行的worker,你可以调用worker的terminate方法:myWorker.terminate();//工作线程会立即终止在工作线程中,工作线程也可以调用自己的close方法关闭:close();错误处理当一个worker在运行中出现错误时,它的onerror事件处理程序将被调用。它将接收一个名为error的事件,该事件扩展了ErrorEvent接口。事件不冒泡,可以取消;为了防止触发默认操作,worker可以调用错误事件的preventDefault()方法。错误事件有以下三个核心字段:message可读的错误信息。filename发生错误的脚本文件的名称。lineno发生错误的脚本文件的行号。如果需要,产生童工可以产生更多的工人。即subworker,但必须托管在同源父页面。注意:subworker解析URI时,会相对于parentworker的地址,而不是自己页面的地址。这使工作人员更容易记录他们之间的依赖关系。导入脚本和库工作线程可以访问一个全局函数importScripts()来导入脚本,它接受0个或多个URI作为参数来导入资源;下面的例子是合法的:importScripts();//什么都不导入importScripts('foo.js');//只引入"foo.jsimportScripts('foo.js','bar.js');//引入两个scripts注意:脚本的下载顺序不固定,执行时会按照传入importScripts()的文件名顺序执行,这个过程是同步完成的,importScripts()要等到所有脚本都下载完才会返回并运行。关于sharedworker一个sharedworker可以被多个脚本使用——即使这些脚本正在被不同的窗口、iframe或worker访问。生成一个sharedworkervarmyWorker=newSharedWorker('worker.js');//constructor不同于dedicatedworkerSharedWorker数据传输和dedicatedworker的区别在于它不同于sharedworkerWorker通信必须通过端口对象,它是脚本通信的确切开放端口与工人(这部分隐含在专用工人中)。在传递消息之前,必须显式打开端口连接,打开方法使用onmessage事件处理器或start()方法://方法1myWorker.port.onmessage=function(e){...}//方法2(只有一种情况需要,即消息事件由addEventListener()方法使用添加。)myWorker.port.start();myWorker.port.addEventListener('message',function(e){...})然后就可以像以前一样收发消息了,但是postMessage()方法必须传给port对象调用:/*mainthread*/myWorker.port.postMessage('Ipostedsomemessage!');//sendmyWorker.port.onmessage=function(e){//listentoreceive...}/*workerthread*/onconnect=function(e){varport=e.ports[0];port.onmessage=function(e){varworkerResult='Result:'+(e.data[0]*e.data[1]);port.postMessage(workerResult);}}在工作线程中需要注意的是:在创建端口连接时(例如:在父线程中,设置onmessage事件处理程序时,或者显式调用start()方法时),使用onconnect事件处理程序来执行代码。还必须在端口连接上访问postMessage()和onmessage之类的东西。兼容桌面功能的浏览器ChromeFirefox(Gecko)InternetExplorerOperaSafari(WebKit)BasicSupport43.5(1.9.1)10.010.64SharedWorker429NotImplemented10.66.1MobileFeaturesAndroidChromeforAndroidFirefoxMobile(Gecko)FirefoxOS(Gecko)IEPhoneOperaMobileSafariMobileBasicSupport4.443.51.0.110.011.55.1sharedworker未实现481.0.1未实现未实现未实现