JavaScript Web Workers的构建块及5个使用场景


当前第2页 返回上一页

1

2

3

4

5

6

7

8

9

10

11

12

<button onclick="startComputation()">Start computation</button>

 

<script>

  function startComputation() {

    worker.postMessage({'cmd': 'average', 'data': [1, 2, 3, 4]});

  }

  var worker = new Worker('doWork.js');

  worker.addEventListener('message', function(e) {

    console.log(e.data);

  }, false);

   

</script>

然后这是 worker 中的 js 代码:

1

2

3

4

5

6

7

8

9

10

11

self.addEventListener('message', function(e) {

  var data = e.data;

  switch (data.cmd) {

    case 'average':

      var result = calculateAverage(data); // 从数值数组中计算平均值的函数

      self.postMessage(result);

      break;

    default:

      self.postMessage('Unknown command');

  }

}, false);

当单击该按钮时,将从主页调用 postMessage。postMessage 行将 JSON 对象传给Worker。Worker 通过定义的消息处理程序监听并处理该消息。

当消息到达时,实际的计算在worker中执行,而不会阻塞事件循环。Worker 检查传递的事件参数 e,像执行 JavaScript 函数一样,处理完成后,把结果传回给主页。

在 Worker 作用域中,this 和 self 都指向 Worker 的全局作用域。

有两种方法可以停止 Worker:从主页调用 worker.terminate() 或在 worker 内部调用 self.close()

Broadcast Channel

Broadcast Channel API 允许同一原始域和用户代理下的所有窗口,iFrames 等进行交互。也就是说,如果用户打开了同一个网站的的两个标签窗口,如果网站内容发生了变化,那么两个窗口会同时得到更新通知。

还是不明白?就拿 Facebook 作为例子吧,假如你现在已经打开 了Facebook 的一个窗口,但是你此时还没有登录,此时你又打开另外一个窗口进行登录,那么你就可以通知其他窗口/标签页去告诉它们一个用户已经登录了并请求它们进行相应的页面更新。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

// Connection to a broadcast channel

var bc = new BroadcastChannel('test_channel');

 

// Example of sending of a simple message

bc.postMessage('This is a test message.');

 

// Example of a simple event handler that only

// logs the message to the console

bc.onmessage = function (e) {

  console.log(e.data);

}

 

// Disconnect the channel

bc.close()

可以从下面这张图,在视觉上来清晰地感受 Broadcast Channel:

3e5b5210fc13d4887a09b9bebe57264.png

Broadcast Channel 浏览器支持比较有限:

e63eff326a3db2fde9e5de1d754f2d8.png

消息的大小

有两种方式发送消息给Web Workers:

  • 复制消息:消息被序列化、复制、发送,然后在另一端反序列化。页面和 Worker 不共享相同的实例,因此最终的结果是每次传递都会创建一个副本大多数浏览器,在两边都是使用的JSON对值进行编码和解码,这样对数据的解码、编码操作,势必会增加消息传输过程的时间开销。信息越大,发送的时间就越长。
  • 传递消息:这意味着原始发送方在一旦发送后不能再使用它。传输数据几乎是瞬间的,这种传输方式的局限性在于只能用 ArrayBuffer 类型来传递。

Web Workers 可用的特性

由于 JavaScript的多线程特性,Web工作者只能访问JavaScript特性的一个子集。以下是它的一些特点:

Web Workers 由于具有多线程特性,因此只能访问 JavaScript 特性的子集。 以下是可使用特性列表:

  • navigator 对象
  • location 对象(只读)
  • MLHttpRequest
  • setTimeout()/clearTimeout() and setInterval()/clearInterval()
  • 应用缓存(Application Cache)
  • 使用 importScripts() 导入外部脚本
  • 创建其他的 Web Workers

Web Workers 的局限性

遗憾的是,Web Workers 无法访问一些非常关键的 JavaScript 特性:

  • DOM(它会造成线程不安全)
  • window 对象
  • document 对象
  • parent 对象

这意味着 Web Worker 不能操作 DOM (因此也不能操作 UI)。有时这可能很棘手,但是一旦你了解了如何正确使用 Web Workers,你就会开始将它们作为单独的“计算机”使用,而所有 UI 更改都将发生在你的页面代码中。 Workers 将为你完成所有繁重的工作,然后一旦完成再把结果返回给 page 页面。

处理错误

和 JavaScript 代码一样,Web workers 里抛出的错误,你也需要进行处理。当 Worker 执行过程中如果遇到错误,会触发一个 ErrorEvent 事件。接口包含了三个有用的属性来帮忙排查问题:

  • filename - 导致 Worker 的脚本名称
  • lineno - 发生错误的行号
  • message - 对错误的描述

例子如下:

b9c86f918ebac5c5616c530ca495704.png

在这里,可以看到我们创建了一个 worker 并开始侦听错误事件。

018089b527d303a5f4fddb0c60ec8fe.png

在 worker 内部(在 workerWithError.js 中),我们通过将未定义 x 乘以 2 来创建一个异常。异常被传播到初始脚本,然后通过页面监听 error事件,对错误进行捕获。

5个好的 Web Workers 应用实例

到目前为止,我们已经列出了 Web Workers 的优点和局限性。现在让我们看看它们最强大的用例是什么:

  • Ray tracing(光线追踪):光线追踪是一种以像素为单位跟踪光的路径生成图像的渲染技术。光线追踪利用 CPU 密集型的数学计算来模拟光的路径。其思想是模拟一些效果,如反射、折射、材料等。所有这些计算逻辑都可以添加到 Web Worker 中,以避免阻塞 UI线程。更好的是――可以很容易地在多个 workers 之间(以及在多个cpu之间)分割图像呈现。下面是一个使用 Web Workers 的光线追踪的简单演示―https://nerget.com/rayjs-mt/r...。
  • Encryption(加密):由于对个人和敏感数据的监管越来越严格,端到端加密越来越受欢迎。加密是一件非常耗时的事情,特别是如果有很多数据需要频繁加密(例如,在发送到服务器之前)。这是一个使用 Web Worker 非常好的场景,因为它不需要访问 DOM 或任何花哨的东西――它是完成其工作的纯算法。只要是在 Web Worker 中工作的,对于端用户就是无缝的,不会影响到体验。
  • Prefetching data(预取数据):为了优化你的网站或 web 应用程序并改进数据加载时间,你可以利用 Web Workers 提前加载和存储一些数据,以便在需要时稍后使用。Web Workers 在这种情况下非常棒,因为它们不会影响应用程序的UI,这与不使用Workers 时是不同的。
  • Progressive Web Apps(渐进式Web应用程序):这种渐进式Web应用程序要求,即使在用户网络不稳定的条件下,也能够迅速的加载。这意味着数据必须本地存储在浏览器中。这也是 IndexDB 或类似 api 发挥作用的地方。通常情况下,客户端的存储都是必要的,但使用起来需要不阻塞UI渲染线程,那么工作就需要在 Worker 中进行了。不过,以IndexDB 为例,它提供了一些异步的API,调用它们的话也不需要使用 web worker,但如果是同步的 API,就必须要在 Worker 中使用了。
  • Spell checking(拼写检查):一个基本的拼写检查程序的工作流程如下-程序读取一个字典文件与一个正确拼写单词列表。字典被解析为一个搜索树,以使实际的文本搜索更有效。当一个单词被提供给检查器时,程序检查它是否存在于预先构建的搜索树中。如果在树中没有找到该单词,可以通过替换替换字符并测试它是否是有效的单词(如果是用户想要写的单词),为用户提供替代拼写。所有的这些处理过程都可以在 Web Worker中进行了,用户可以不被阻塞的输入词汇和句子,Web Worker 在后台校验词汇是否正确以及提供备选词汇。

想了解更多编程学习,敬请关注php培训栏目!

以上就是JavaScript Web Workers的构建块及5个使用场景的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

exports和module.expors之间有什么区别及联系?

javascript怎么将对象转换为数组

javascript字符串大小写怎么转换

javascript中input怎么用

学会html能做什么工作

javascript声明变量的4种方法是什么

javascript字符串截取方法有哪些?

分享dom中的表单操作,节点操作

javascript怎么改字体大小

javascript怎么删除行

更多相关阅读请进入《javascript》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...