HTML5知识填坑(五)——Web Workers

我们知道,js是单线程的,并且和渲染线程是互斥的。也就是说,在浏览器中,执行js代码和渲染页面不能同时进行。这种机制会造成这样一种情况,如果我们的js代码运行的时间过长,这样UI更新就没有时间进行,就会造成用户界面的锁定。

为了缓解这个问题,浏览器制定了长时间运行脚本的限制。但作为web开发人员,为了良好的用户体验,我们的代码运行时间应该远远小于浏览器的限制,研究表明,单个js的运行时间 不应该超过100ms,这样的大小是保证用户体验的上限。

然而在实际开发中,难免会有复杂的任务不能在100ms内完成。这个时候,最理想的办法是让出时间片,停止执行js,让UI有机会更新。于是js定时器走进了我们的视野。定时器可以让我们在一段时间后再将js任务加入任务队列。在这之间,我们就可以来进行UI更新。

但我们考虑这样一种情况,如果我们要执行的是一个消耗异常大的任务,定时器也难以很好的完成,那该怎么办?

Web Worker就可以帮助我们很好的解决这个问题。
Web Worker为我们提供了一种在浏览器UI线程之外运行脚本的方法。也就是说,Web Worker代码的运行不会占用浏览器UI线程的时间。Worker 接口会生成真正的操作系统级别的线程,每个worker会在自己的线程中运行代码。这意味着worker运行代码不仅不会影响浏览器UI,也不会影其他Worker中运行的代码。

听起来是不是感觉很强大,下面我们就来具体看看。

1.Worker的运行环境

我们能够明白为什么js线程和渲染线程一定要是互斥的,同理,web worker也不被允许访问非线程安全的组件或者是 DOM。

一个worker是使用一个构造函数创建的一个对象,运行一个命名的JavaScript文件 ,这个文件包含将在工作线程中运行的代码,workers 运行在另一个全局上下文中,不同于当前的window。每个Web Worker都有自己的全局运行环境。

也正是因为如此,我们无法从JS代码中创建它,实际上,你需要创建一个完全独立的JS文件,其中包含需要在Worker中运行的代码。

2.使用

生成Worker

//index.html
var myWorker = new Worker("code.js");//create a worker

myWorker.onmessage = function (event) {
  console.log(e.data);
};

myWorker.postMessage("Amy");// start the worker.
//code.js

self.onmessage=function(e){
  self.postMessage("hello"+e.data);
}

一旦 myWorker = new Worker(“code.js”)执行,将为这个文件创建一个新的线程和一个新的Worker运行环境。该文件会被异步下载,直到为文件下载并执行完成后才会启动此worker。

Worker与网页代码就是通过事件接口通信。通过postMessage()方法发消息,通过onmessage事件接收消息。这也是他们进行通信的唯一途径。

worker 与主页面之间传输的 消息 始终是 「JSON 消息」,即使它是一个原始类型的值。所以,你完全可以传输 JSON 数据 和/或 任何能够序列化的数据类型。有效数据会被序列化,传入或传出worker,然后反序列化。

在主页面与 worker 之间传递的数据是通过拷贝,而不是共享来完成的。页面与 worker 不会共享同一个实例,最终的结果就是在每次通信结束时生成了数据的一个副本。

加载外部文件
Worker通过importScripts()方法加载外部JS文件,该方法接受一个或多个JS文件的URL作为参数。importScripts()的调用过程是阻塞式的,直到所有文件加载并执行完后,脚本才会继续执行。由于worker在UI线程之外,所以这种阻塞并不会形象UI响应。

importScripts("a.js","b.js");

self.onmessage=function(e){
    self.postMessage("hello"+e.data);
}

参考文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值