一文读懂web worker究竟能干什么?
/ / 点击 / 阅读耗时 8 分钟Web workers
提供了一种在浏览器中单线程运行 js
代码的方法。单线程处理请求显示内容以及通过键盘、鼠标点击,和其他设备产生的用户交互, 以及对 AJAX
请求的响应。事件处理和AJAX请求虽然是异步的,但是它们本质仍然在单线程中运行,必须要尽可能的快去完成。否则,浏览器中的就会停止响应,直到任务处理完成。
Web workers
允许 js
代码在单独的线程中运行,完全独立于浏览器线程及其通常的活动。
今年来关于对 Web workers
的使用有很多的争论,这几年cpu的运算速度是非常快的,几乎所有的个人电脑都有几个G的内存。同样,移动设备已经越来越接近台式机cpu速度和的内存大小。
曾经被认为是计算密集型的应用现在被认为不是那么糟糕了。
然后真实的情况却是
但是很多时候,我们只考虑在开发环境中测试的一个应用程序的执行。而在用户侧,可能同时会进行多个应用。
因此,在隔离状态下运行的应用程序可能不需要使用Web workers
,但是有必要使用它们为各种用户提供最佳体验。
一下代码演示了如何创建一个 Web workers
:
1 | new Worker('my-worker.js') |
一旦创建了 web worker
,它就在独立于主浏览器线程的单独线程中运行,执行脚本中给定给它的任何代码。
在worker和js主线程之间传递数据:
- 发送端上的postMessage()函数
- 接收端上的消息事件处理程序
消息事件处理程序接收事件参数,与其他事件处理程序一样;此事件有一个“data”属性,其中包含从另一端传递过来的任何数据。
1 | var worker = new Worker("demo1-hello-world.js"); |
1 | // demo1-hello-world.js |
上面代码的输出结果:
1 | Message posted from webworker: Worker running |
worker是常驻进程存在的
在一个 worker
的生命周期中,可以在浏览器和 worker
之间发送和接收多个消息。
web workers
以两种方式确保代码安全、无冲突的执行:
- 工作线程的独立、隔离的全局环境,独立于浏览器环境
- 使用postMessage()在主线程和工作线程之间进行消息传递
每个 worker
线程都有一个独立的全局环境,该环境与浏览器页面的 js
环境不同。worker
线程根本不能访问页面的 js
环境中的任何东西——DOM
、window
或 document
对象都不行。
此外,通过 postMessage()
传递的任何数据在传递之前都会被复制,因此更改主线程中的数据不会导致 worker
线程中的数据发生更改。这提供了固有的保护,避免在主线程和 worker
线程之间传递的数据发生冲突的并发更改。
web worker的典型应用场景
典型应用:执行运算需要消耗大量的CPU时间或采取一个不可预知的时间来访问数据。
举例说明:
- 预取或缓存数据供以后使用
- 轮询和处理来自web服务的数据
- 大数据集的处理和显示
- 游戏中与移动相关的计算
- 图像处理和过滤
- 处理文本数据(代码语法、拼写检查、字数)
CPU时间是最简单的使用,但是对网络资源的请求也非常重要。
很多时候,internet上的网络通信可以在几毫秒内执行,但有时网络资源变得不可用,直到网络恢复或请求超时才会停止(这可能需要1-2分钟才能清除)。
而且,有些代码在开发环境中单独测试时可能不需要很长时间就可以运行,但当多个应用同时运行时,它可能成为在用户环境中运行的问题。
分享几个实际案例
最终的想法
针对浏览器的兼容判断,可以通过一个简单的判断 if (typeof Worker !== "undefined")
来创建和保护的我们的 web worker
, 在 web worker
外部执行相同的代码(例如:setTimeout或requestAnimationFrame)