原文地址:https://blog.sessionstack.com/how-javascript-works-the-building-blocks-of-web-workers-5-cases-when-you-should-use-them-a547c0757f6a

How JavaScript works: The building blocks of Web Workers + 5 cases when you should use them

JavaScript的工作原理:Web Workers的构建块+当您应该使用它们时的5个案例

您应该已经熟悉JavaScript在单个线程上运行的事实,正如我们之前非常详细地讨论过的那样。但是,JavaScript为开发人员提供了编写异步代码的机会。

异步编程的局限性

异步编程使您的应用程序UI能够及时响应,通过“调度”部分代码在事件循环中稍后执行,从而允许首先执行UI呈现。

异步编程的一个很好的用例就是发出AJAX请求。由于请求可能需要花费大量时间,因此可以异步进行,并且在客户端等待响应时,可以执行其他代码。

//This is assuming that you're using jQuery
jQuery.ajax({url:'https://api.example.com/endpoint',success:function(response) {//Code to be executed when a response arrives.
}
});

但是,这会产生一个问题 - 请求由浏览器的WEB API处理,但其他代码如何异步?例如,如果成功回调内部的代码非常占用CPU,那该怎么办:

var result = performCPUIntensiveCalculation();

如果performCPUIntensiveCalculation不是HTTP请求而是阻塞代码(例如巨大的for循环),则无法释放事件循环并取消阻止浏览器的UI - 它将冻结并对用户无响应。

这意味着异步函数只解决了JavaScript语言的一小部分单线程限制。

在某些情况下,使用setTimeout可以在长时间运行的计算中取消阻止UI,从而获得良好的效果。例如,通过在单独的setTimeout调用中对复杂计算进行批处理,您可以将它们放在事件循环中的不同“位置”上,这样就可以花时间来执行UI呈现/响应。

我们来看一个计算数值数组平均值的简单函数:

functionaverage(numbers) {var len =numbers.length,sum= 0,i;if (len === 0) {return 0;}for (i = 0; i < len; i++) {sum+=numbers[i];}return sum /len;
}

这就是你如何重写上面的代码并“模拟”异步性:

functionaverageAsync(numbers, callback) {var len =numbers.length,sum= 0;if (len === 0) {return 0;}functioncalculateSumAsync(i) {if (i <len) {//Put the next function call on the event loop.setTimeout(function() {sum+=numbers[i];calculateSumAsync(i+ 1);},0);}else{//The end of the array is reached so we're invoking the callback.callback(sum /len);}}calculateSumAsync(0);
}

这将使用setTimeout函数,该函数将在事件循环中进一步添加计算的每个步骤。在每次计算之间,将有足够的时间进行其他计算,这是解冻浏览器所必需的。

Web Workers将拯救你

HTML5为我们带来了许多开箱即用的好东西,包括:

  • SSE
  • Geolocation
  • Application cache
  • Local Storage
  • Drag and Drop
  • Web Workers

Web Workers是浏览器中的线程,可用于执行JavaScript代码而不会阻止事件循环。

这真是太神奇了。 JavaScript的整个范例都是基于单线程环境的思想,但Web Workers可以删除(部分)这种限制。

Web Workers允许开发人员在后台运行长时间运行且计算密集的任务,而不会阻止UI,从而使您的应用程序更具响应性。更重要的是,为了破解事件循环的方式,不需要使用setTimeout的技巧。

这是一个简单的演示,显示了使用和不使用Web Workers对数组进行排序的区别。

Web Worker概述

Web Workers允许您执行一些操作,例如启动长时间运行的脚本来处理计算密集型任务,但不会阻止UI。实际上,这一切都是并行发生的。 Web Workers是真正的多线程。

您可能会说 - “JavaScript不是单线程语言吗?”。

当你意识到JavaScript是一种没有定义线程模型的语言时,这应该是你的“啊哈!”时刻。 Web Workers不是JavaScript的一部分,它们是可以通过JavaScript访问的浏览器功能。大多数浏览器历来都是单线程的(当然,这已经改变了),并且大多数JavaScript实现都发生在浏览器中。 Web Worker没有在Node.JS中实现 - 它有一个“cluster”或“child_process”的概念,它有点不同。

值得注意的是,该规范提到了三种类型的Web Worker:

  • Dedicated Workers
  • Shared Workers
  • Service workers

Dedicated Workers(专用Workers)

专用Web Worker由主进程实例化,只能与之通信。

Shared Workers(共享Workers)

在同一来源(不同的浏览器选项卡,iframe或其他共享工作者)上运行的所有进程都可以访问共享工作者。

Service Workers(服务Workers)

服务工作者是针对原点和路径注册的事件驱动的工作者。它可以控制与之关联的网页/网站,拦截和修改导航和资源请求,以及以非常精细的方式缓存资源,让您可以很好地控制应用在特定情况下的行为(例如,当网络不是可用。)

在这篇文章中,我们将专注于“专用Workers”,并将他们称为“Web Workers”或“Workers”。

Web Worker是如何工作的

Web Workers是以.js的文件形式来呈现的,这些文件通过页面中的异步HTTP请求被引进来。 Web Worker API完全隐藏了这些请求。

Workers利用类似线程的消息传递来实现并行性。它们非常适合用户保持UI最新,高性能和响应性。

Web Workers在浏览器中的独立线程中运行。因此,它们执行的代码需要包含在单独的文件中。记住这一点非常重要。

让我们看看如何创建基本的Worker:

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

如果“task.js”文件存在且可访问,则浏览器将生成一个新线程,该线程异步下载该文件。下载完成后,它将立即执行,worker将开始。
如果提供的文件路径返回404,则工作程序将以静默方式失败。

要启动创建的worker,需要调用postMessage方法:

worker.postMessage();

Web Worker通信

为了在Web Worker和创建它的页面之间进行通信,您需要使用postMessage方法或广播通道。

postMessage方法

较新的浏览器支持JSON对象作为方法的第一个参数,而较旧的浏览器仅支持字符串。

让我们看一个示例,通过将JSON对象作为一个更“复杂”的示例传递,创建工作者的页面如何与之来回通信。传递一个字符串是完全一样的。

让我们看看下面的HTML页面(或者更精确的部分):

<button οnclick="startComputation()">Start computation</button><script>functionstartComputation() {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脚本:

self.addEventListener('message', function(e) {var data =e.data;switch(data.cmd) {case 'average':var result = calculateAverage(data); //Some function that calculates the average from the numeric array.
self.postMessage(result);break;default:self.postMessage('Unknown command');}
},false);

单击该按钮时,将从主页面调用postMessage。 worker.postMessage行将JSON对象传递给worker,添加cmd和数据键及其各自的值。 worker将通过定义的消息处理程序处理该消息。

当消息到达时,实际计算正在worker中执行,而不会阻止事件循环。worker正在检查传递的事件e并像标准JavaScript函数一样执行。完成后,结果将传递回主页面。

在worker的上下文中,self和this都引用了worker的全局范围。

有两种方法可以停止worker:通过从主进程中调用worker.terminate()或通过调用worker本身内部的self.close()。

Broadcast Channel

广播频道是一种更通用的通信API。它允许我们向共享相同来源的所有上下文广播消息。从同一来源提供的所有浏览器标签,iframe或worker都可以发送和接收消息:

//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()

在视觉上,您可以看到广播频道的外观更清晰:

广播频道的浏览器支持有限:

消息的大小

有两种方法可以向Web Workers发送消息:

  • 复制消息:消息被序列化,复制,发送,然后在另一端反序列化。页面和worker不共享同一个实例,因此最终结果是每次传递都会创建一个副本。大多数浏览器通过自动JSON编码/解码任一端的值来实现此功能。正如所料,这些数据操作为消息传输增加了大量开销。消息越大,发送的时间越长。
  • 转移邮件:这意味着原始发件人一旦发送就无法再使用它。传输数据几乎是即时的。限制是只有ArrayBuffer可以转移。

Web Workers可用的功能

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

  • The navigator object
  • The location object (read-only)
  • XMLHttpRequest
  • setTimeout()/clearTimeout() and setInterval()/clearInterval()
  • The Application Cache
  • Importing external scripts using importScripts()
  • Creating other web workers

Web Worker的局限

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

  • The DOM (it’s not thread-safe)
  • The window object
  • The document object
  • The parent object

这意味着Web Worker无法操纵DOM(以及UI)。它有时会很棘手,但是一旦你学会了如何正确使用Web Workers,你就会开始将它们作为单独的“计算机器”使用,而所有的UI更改都将在你的页面代码中进行。Worker将为您完成所有繁重的工作,一旦完成工作,您将把结果传递给对UI进行必要更改的页面。

处理错误

与任何JavaScript代码一样,您将需要处理Web Workers中引发的任何错误。如果在执行worker时发生错误,则会触发ErrorEvent。该界面包含三个有用的属性,用于确定出现了什么问题:

  • filename - 导致错误的工作程序脚本的名称
  • lineno - 发生错误的行号
  • message - 错误的描述

以下是示例:

functiononError(e) {console.log('Line: ' +e.lineno);console.log('In: ' +e.filename);console.log('Message: ' +e.message);
}var worker = new Worker('workerWithError.js');
worker.addEventListener('error', onError, false);
worker.postMessage();//Start worker without a message.

self.addEventListener('message', function(e) {postMessage(x* 2); //Intentional error. 'x' is not defined.
};

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

在worker内部(在workerWithError.js中),我们通过将x乘以2来创建故意异常,而x未在该范围中定义。异常传播到初始脚本,并且正在调用onError以及有关错误的信息。

Web Worker的好用例

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

  • 光线跟踪:光线跟踪是一种渲染技术,用于通过将光线路径跟踪为像素来生成图像。光线跟踪使用非常耗费CPU的数学计算来模拟光的路径。这个想法是模拟一些效果,如反射,折射,材料等。所有这些计算逻辑都可以添加到Web Worker中,以避免阻塞UI线程。更好的是 - 您可以轻松地在几个工作者(以及几个CPU之间)之间分割图像渲染。以下是使用Web Workers进行光线跟踪的简单演示 - https://nerget.com/rayjs-mt/rayjs.html。
  • 加密:由于对个人和敏感数据的监管越来越严格,端到端加密越来越受欢迎。加密可能是非常耗时的事情,特别是如果有大量数据必须经常加密(例如,在将其发送到服务器之前)。这是一个非常好的场景,可以使用Web Worker,因为它不需要任何访问DOM或任何花哨的东西 - 它是纯粹的算法来完成它们的工作。一旦进入工作人员,它对最终用户是无缝的,并且不会影响他们的体验。
  • 预取数据:为了优化您的网站或Web应用程序并缩短数据加载时间,您可以利用Web Workers提前加载和存储一些数据,以便以后在需要时使用它。在这种情况下,Web Workers非常棒,因为它们不会影响应用程序的UI,这与没有工作人员的情况不同。
  • 渐进式Web应用程序:即使网络连接不稳定,也必须快速加载。这意味着数据必须本地存储在浏览器中。这是IndexDB或类似API发挥作用的地方。基本上,需要客户端存储。为了在不阻塞UI线程的情况下使用,必须在Web Workers中完成工作。好吧,在IndexDB的情况下,有一个异步API,即使没有工作人员也允许你这样做,但之前有一个同步API(可能会再次引入),它只能在worker中使用。
  • 拼写检查:基本的拼写检查工具按以下方式工作 - 程序读取带有正确拼写单词列表的字典文件。该字典被解析为搜索树,以使实际文本搜索有效。当向检查器提供单词时,程序检查它是否存在于预构建的搜索树中。如果在树中找不到该单词,则可以通过替换替换字符来为用户提供替代拼写,并测试它是否是有效单词 - 如果它是用户想要写的单词。所有这些处理都可以轻松卸载到Web Worker,这样用户只需键入单词和句子而不会阻止UI,而工作人员可以执行所有搜索和提供建议。

—— 完 ——


转载于:https://www.cnblogs.com/bbcfive/p/10665773.html

[翻译]Review——How JavaScript works:The building blocks of Web Workers相关推荐

  1. The Building Blocks of Interpretability

    Interpretability techniques are normally studied in isolation. We explore the powerful interfaces th ...

  2. Intel Thread Building Blocks (TBB) 入门篇

    一.什么是TBB TBB(Thread Building Blocks)是英特尔发布的一个库,全称为 Threading Building Blocks.TBB 获得过 17 届 Jolt Produ ...

  3. TBB(Intel Threading Building Blocks)学习笔记

    TBB(Intel Threading Building Blocks)学习笔记 并行与并发是相对的,OS里讲的是并发而在 架构 方面更多的是说并行.并行是分多个层面的,个人认为基本上可以分为这么几个 ...

  4. TBB(Intel Threading Building Blocks)并行化

    并行与并发是相对的,OS里讲的是并发而在架构方面更多的是说并行.并行是分多个层面的,个人认为基本上可以分为这么几个层面:1.指令级的并行:即所谓的微程序.指令流水线等,现在cpu的一级缓存.二级缓存都 ...

  5. 乐高机器人骨奥_乐高机器人-Building blocks robot

    乐高机器人-Building blocks robot 一款趣味性强又能触发儿童动手动脑的玩具可以在玩耍的过程中无形开发大脑智慧.乐高机器人就是这样一款玩具.集合了可编程主机.电动马达.传感器.Leg ...

  6. 翻译-高质量JavaScript代码书写基本要点(转载)

    by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=1173 原文作者:S ...

  7. [翻译]Keeping your JavaScript out of the global scope

    Source Website (翻译练手) 2017年12月15日 Keeping your JavaScript out of the global scope (and why you want ...

  8. iText in Action 2nd5.2节(Events for basic building blocks)读书笔记

    前言 在我们将一些基本构建块(Chunk,Paragraph,Chapter等)添加到Document对象的实例中是,基本的构建块是由PdfWriter对象转换为pdf语法.在这个过程中,有一个我们很 ...

  9. [翻译] 物理引擎javascript实现

    转自: How Physics Engines Work 高中物理全还给老师了啊啊啊啊啊啊 牛顿第二定律 物体加速度的大小跟物体受到的作用力成正比,跟物体的质量成反比,加速度的方向跟合外力的方向相同. ...

  10. 《Patterns, Principles, and Pract》— chapter14 Introducing the Domain Modeling Building Blocks

    在该章节里面有如下内容: 从战术的角度创建高效的面向对象的领域模型 介绍value objects, entities, domain services, modules ,通过这些为domain和行 ...

最新文章

  1. 250鲁大师跑分_看了鲁大师跑分,会发现MX250独显笔记本已落伍了
  2. 路由器与集线器、交换机的根本区别
  3. BZOJ1257 [CQOI2007]余数之和
  4. 周志华教授签名新书免费送!豆瓣满分森林书破解AI实践难题
  5. DIY一只机器狗需要多少钱?最低仅900美元,斯坦福大学出品,代码已开源
  6. [译]C#中的条件断点
  7. mysql操作json优点和缺点_MySQL与JSON-为什么?
  8. bin文件如何编辑_如何为高通固件创建rawprogram0和patch0文件
  9. sqlyog设置简体中文_SQLyog中文版使用教程
  10. 基于visual Studio2013解决C语言竞赛题之1077大数相加
  11. Java url转MultipartFile inputStream转File file转multipartFile
  12. HTMLpre代码美化
  13. MySQL原理 - InnoDB引擎 - 行记录存储 - Redundant行格式
  14. 计算机三级嵌入式系统知识点考查(易错)
  15. 小型微型计算机怎么样,电脑小主机怎么样,全方位分析小型电脑主机优缺点
  16. 解决AMD Software提示图形驱动版本不匹配问题
  17. 每天3分钟知晓天下事,一句话新闻资讯简报的公众号推荐
  18. java 安卓客户端开发_《安卓网络编程》之第一篇 java环境下模拟客户端、服务器端...
  19. 使用MySQLDUMP进行数据库逻辑备份与恢复
  20. 记一次·ulimit: open files: cannot modify limit:不允许操作

热门文章

  1. 设计模式系列 - 装饰器模式
  2. 三个linux系统共存,修改默认启动
  3. Oracle数据库基础知识_数值类型及函数
  4. 分子量 (Molar Mass,ACM/ICPC Seoul 2007,UVa 1586)
  5. c += c-- | ++b;
  6. 自动生成 Makefile 的全过程详解! automake/autoconf 入门
  7. ASP.NET 实现文件下载
  8. Leetcode705.Design HashSet设置哈希集合
  9. UVa 10491 - Cows and Cars(全概率)
  10. WeBack(微信聊天记录导出)使用教程