资讯专栏INFORMATION COLUMN

Web Worker API

kidsamong / 2946人阅读

摘要:原因是,在内部,是有效的全局作用域。错误事件有以下三个核心的字段可读性良好的错误消息。发生错误的脚本文件名。在传递消息之前,端口连接必须被显式的打开,打开方式是使用事件处理函数或者方法方式方式只在一种情况下需要,那就是消息事件被方法使用。

简介

  Web Worker可以理解为js在后台线程中运行的方法,它可以执行js代码而不阻塞用户UI界面。一个Web Worker可以将消息发送到创建它的JavaScript代码(只要运行在同源的父页面中,workers可以依次生成新的workers), 反之也可以从主线程接收消息
  注意:worker运行在另一个全局上下文中,不同于当前的window。因此,使用window快捷方式获取当前全局的范围,在一个Worker内将返回错误(直接访问你需要访问的属性即可!如:console而不是window.console)。

worker中可用函数和接口

在WebWorker中有些方法和属性是不能被访问的,比如BOM的一些API和DOM相关的一些API,localStorage,SessionStorage等,但是大部分的window对象是可以被访问的比如:Websocket,XMLHttpRequest(同样不能跨域☹)Console Api,Array,Date,Math,String等等,就是说涉及到页面操作和页面中的对象统统不能被访问,它的应用场景是替代主线程执行需要消耗页面性能的代码。这里有一份关于WebWorker允许访问的方法及属性清单

主要wroker类型

常用worker为专用worker(仅在单一脚本中被使用)和共享worker(以同时被多个脚本使用);DedicatedWorkerGlobalScope和SharedWorkerGlobalScope对象分别代表它们的上下文

使用

为了更好的错误处理控制及向下兼容需要做些兼容检测

if (window.Worker) {
    some codes ...
}
生成Worker

调用Worker()构造函数创建一个Worker对象,该对象接收指定的URL脚本(脚本必须遵守同源策略否则将抛出错误)

var myWorker = new Worker("worker.js");
数据传递

  主线程和worker线程都使用postMessage()方法发送各自的消息,使用onmessage事件处理函数来响应消息(消息被包含在Message事件的data属性中),这个过程中数据并不是被共享而是被复制。在主线程中使用时,onmessage和postMessage() 必须挂在worker对象上,而在worker中使用时不用这样做。原因是,在worker内部,worker是有效的全局作用域。

/*主线程*/
//发送数据至worker
myWorker.postMessage("can you hear me?");
//从worker线程监听接收数据
myWorker.onmessage = function(e) {
    console.log(e.data);//"I can hear you!"
}

/*worker线程*/
//从主线程监听接收数据
onmessage = function(e) {
    console.log(e.data);//"can you hear me?"
    //发送数据至worker
    e.data && postMessage("I can hear you!");
}
终止worker

如果你需要从主线程中立刻终止一个运行中的worker,可以调用worker的terminate方法:

myWorker.terminate();//worker 线程会被立即杀死

在worker线程中,workers 也可以调用自己的close方法进行关闭:

close();
错误处理

当worker出现运行中错误时,它的onerror事件处理函数会被调用。它会收到一个扩展了 ErrorEvent 接口的名为 error的事件。该事件不会冒泡并且可以被取消;为防止触发默认动作,worker可以调用错误事件的preventDefault()方法。

错误事件有以下三个核心的字段:
message
可读性良好的错误消息。
filename
发生错误的脚本文件名。
lineno
发生错误时所在脚本文件的行号。

生成子worker

如果需要worker能够生成更多的worker。即subworker,但必须托管在同源的父页面内。注意:subworker解析 URI时会相对于父worker的地址而不是自身页面的地址。这使得worker更容易记录它们之间的依赖关系。

引入脚本与库

Worker 线程能够访问一个全局函数importScripts()来引入脚本,该函数接受0个或者多个URI作为参数来引入资源;以下例子都是合法的:

importScripts();//什么都不引入
importScripts("foo.js");//只引入"foo.js
importScripts("foo.js", "bar.js");//引入两个脚本

注意: 脚本的下载顺序不固定,但执行时会按照传入 importScripts() 中的文件名顺序进行。这个过程是同步完成的;直到所有脚本都下载并运行完毕, importScripts() 才会返回。

关于共享worker

一个共享worker可以被多个脚本使用——即使这些脚本正在被不同的window、iframe或者worker访问。

生成共享worker
var myWorker = new SharedWorker("worker.js");//和专用worker不同构造器为SharedWorker
数据传递

和专用worker不同的是与一个共享worker通信必须通过端口对象即一个确切的打开的端口供脚本与worker通信(在专用worker中这一部分是隐式进行的)。

在传递消息之前,端口连接必须被显式的打开,打开方式是使用onmessage事件处理函数或者start()方法:

//方式1
myWorker.port.onmessage = function(e) {
    ...
}
//方式2(只在一种情况下需要,那就是消息事件被addEventListener()方法使用。)
myWorker.port.start();
myWorker.port.addEventListener("message",function(e){
    ...
})

然后就可以像之前那样发送和接收消息了,但是postMessage()方法必须被端口对象调用:

/*主线程*/
myWorker.port.postMessage("I posted some message!");//发送
myWorker.port.onmessage = function(e) {//监听接收
    ...
}

/*worker线程*/
onconnect = function(e) {
    var port = e.ports[0];
    port.onmessage = function(e) {
        var workerResult = "Result: " + (e.data[0] * e.data[1]);
        port.postMessage(workerResult);
    }
}

在worker线程中需要注意的是:当一个端口连接被创建时(例如:在父级线程中,设置onmessage事件处理函数,或者显式调用start()方法时),使用onconnect事件处理函数来执行代码。诸如postMessage()和onmessage也必须在端口连接上访问。

浏览器兼容 Desktop
特性 Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
基础支持 4 3.5 (1.9.1) 10.0 10.6 4
共享worker 4 29 未实现 10.6 6.1
Mobile
特性 Android Chrome for Android Firefox Mobile (Gecko) Firefox OS (Gecko) IE Phone Opera Mobile Safari Mobile
基础支持 4.4 4 3.5 1.0.1 10.0 11.5 5.1
共享worker 未实现 4 8 1.0.1 未实现 未实现 未实现

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95847.html

相关文章

  • [翻译]Service workers:PWA背后的英雄

    摘要:如果返回的被拒,另一个同步事件被自动地开始重试操作,直到返回一个成功状态的。推送机制使得服务器能够向发送信息,然后将信息展示给用户才是消息通知。然后它们可以发送消息通知,或者是更新的状态。 原文地址:https://medium.freecodecamp.org/service-workers-the-little-heroes-behind-progressive-web-apps-...

    snifes 评论0 收藏0
  • PWA 知不知

    摘要:类似于我们熟知的,可以脱离主线程,处理一些脏累活,干完后通过向主线程汇报工作结果。所以,也是脱离主线程的存在,与不同的是,具有持久化的能力。什么是 PWA Progressive Web App, 简称 PWA,是「渐进式」提升 Web App 体验的一种新方法,能给用户类似原生应用的体验。 「高可靠,高性能,优体验」是 PWA 惯用的形容词,他的另外一个优点就是「渐进式」,开发者可以对照 ...

    MartinDai 评论0 收藏0

发表评论

0条评论

kidsamong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<