JavaScript多线程,网页多线程

  JavaScript多线程,网页多线程

  HTML5总是被谈论。太多的功能和有趣的API让人耳目一新。但是很多童鞋还停留在语义阶段,忽略了HTML5的强大。

  在这一节中,我们来讨论多线程网络工作者。

  一、明确 JavaScript 是单线程

  JavaScript的一个特点就是单线程,也就是一次只能做一件事。

  听起来很奇怪,为什么不设计多线程来提高效率?我们可以假设一个场景:

  假设JavaScript同时有两个线程,一个线程向DOM节点添加内容,另一个线程删除节点。浏览器应该以哪个线程为标准?

  JavaScript作为一种浏览器脚本语言,主要用于与用户交互和操作DOM。

  这就决定了它只能单线程,否则会带来复杂的同步问题。为了避免复杂,JavaScript从诞生之日起就是单线程的,这也成为了这种语言的核心特征。估计短期内很难改变。

  二、新曙光:Web Worker

  单线程始终是一个痛点。为了利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许JavaScript脚本创建多线程。但是子线程完全由主线程控制,不能操作DOM。

  所以这个新标准并没有改变JavaScript单线程的本质。

  Web Workers是现代浏览器提供的JavaScript多线程解决方案,我们可以找到很多使用场景:

  1.我们可以用Web Worker做一些计算量大的操作;

  2.可以实现轮询来改变一些状态;

  3.更新报头的消息状态,例如报头中消息数量的通知;

  4.高频的用户交互,比如拼写检查,根据用户的输入习惯、历史记录、缓存等信息,帮助用户完成输入纠错和修正功能。

  5.加密:加密有时非常耗时,尤其是当您需要频繁加密大量数据时(例如,在将数据发送到服务器之前加密数据)。

  6.预取数据:为了优化网站或网络应用,提高数据加载时间,可以使用Workers。

  以备不时之需。

  加密是使用Web Worker的绝佳场景,因为它不需要访问DOM或使用其他魔法,它只是使用算法进行计算。随着公众对个人敏感数据的日益重视,信息安全和加密成为重中之重。这在最近的12306用户数据泄露事件中就可以体现出来。

  一旦在Worker中进行计算,对用户来说就是无缝的,不会影响用户体验。

  三、兼容性

  四、基本概念

  1.首先记得判断是否支持。

  如果(窗口。工人){.}2.创建一个新的工人非常简单

  const my Worker=new Worker( Worker . js );postMessage()方法和onmessage事件处理程序是Workers的黑魔法。

  3.postMessage用于发送消息,onmessage用于监控消息。

  const Worker=new Worker( src/Worker . js );worker . on message=e={ console . log(e . data);};Worker.postMessage(你好!);在主线程中使用时,onmessage和postMessage()必须挂在worker对象上,而不是挂在worker中。原因是在worker内部,worker是一个有效的全局范围。

  4.异常处理:

  worker . on error=function(error){ console . log(error . message);投掷误差;};5.解雇工人

  worker . termin ate();工作线程将立即被终止,并且它将没有机会完成自己的操作或清理。

  6.在worker线程中,worker也可以调用自己的close方法来关闭:

  close();五、快速开始

  为了快速掌握,我们举个小例子:项目结构如下

  index.htmlsrcmain . jsworker . jshtml

  html head title web Work Demo/title meta charset= UTF-8 //head body div id= app Hello Jartto!/div script src= src/main . js /script/body/html main . js

  const Worker=new Worker( src/Worker . js );worker . on message=e={ const message=e . data;console . log(`[来自Worker]:$ { message } `);document.getElementById(app )。innerHTML=message};Worker.postMessage(写得真好!);Work.js

  on message=e={ const message=e . data;console . log(`[From Main]:$ { message } `);if(message . index of( good )-1){ postMessage(谢谢支持);}};代码非常简单。主线程发:“写得好!」

  web worker收到消息,发现内容包含“好”字,发回主线程:“谢谢支持”

  六、局限性

  1.在worker内部,不能直接操作DOM节点,也不能使用window对象的默认方法和属性。但是我们可以在window对象下使用大量的东西,包括WebSockets,IndexedDB,以及FireFox OS专用的Data Store API等数据存储机制。

  这里有一个例子,我们修改main.js:

  const Worker=new Worker( src/Worker . js );worker . on message=e={ const message=e . data;console . log(`[来自Worker]:$ { message } `);document.getElementById(app )。innerHTML=message};worker . on error=function(error){ console . log(error);worker . termin ate();};Worker.postMessage(写得真好!);然后修改work.js

  alert( jar tto );on message=e={ const message=e . data;console . log(`[From Main]:$ { message } `);if(message . index of( good )-1){ postMessage(谢谢支持);}};此时,操作将报告:

  这是因为:worker.js执行的上下文和主页面HTML执行的上下文不一样。最顶层的对象不是执行Window和woker.js的全局上下文,而是WorkerGlobalScope,我们会详细解释。

  2.workers与主线程之间的数据传输是通过这样一种消息机制来进行的:双方使用postMessage()方法发送各自的消息,使用onmessage事件处理函数响应消息(消息包含在消息事件的data属性中)。

  在这个过程中,数据不是共享的,而是复制的。

  3.同源限制

  分配给工作线程的脚本文件必须与主线程的脚本文件相同。

  4.文件限制

  工作线程无法读取本地文件,也就是无法打开本地文件系统(file://),加载的脚本必须来自服务器。

  5.不允许本地文件。

  未捕获的SecurityError:无法创建工作进程:

  在(path)/worker.js 处编写脚本

  无法从原点“null”访问。

  Chrome不允许你从本地文件运行脚本时加载web workers。

  那怎么解决呢?我们可以启动一个本地服务器。推荐使用http-server,比较好用。

  6.内容安全政策

  与创建它的文档对象不同,worker有自己的执行上下文。因此,一般来说,工作者不受创建它的文档(或父工作者)的内容安全策略的限制。

  我们举个例子。假设一个文档有以下头声明:

  content-security-policy:script-src self 该语句部分用于禁止其中包含的脚本代码使用eval()方法。但是,如果脚本代码创建了一个worker,那么在worker上下文中执行的代码可以使用eval()。

  为了将CSP分配给工作者,必须将CSP添加到发送工作者代码本身的请求中。

  有一个例外,即如果工作脚本的源是一个全局唯一标识符(例如,它的URL指定一个数据模式或blob),则该工作脚本将继承创建它的工作脚本的文档或CSP。

  七、扩展:WorkerGlobalScope

  关于,我们可以在MDN上找到文档:

  1.自我:

  我们可以使用WorkerGlobalScope的self属性来获取这个对象本身的引用。

  2.位置:

  location属性返回创建线程时与线程相关联的WorkerLocation对象,它代表用于初始化该工作线程的足迹资源的绝对URL。即使页面被多次重定向,这个URL资源的位置也不会改变。

  3.关闭:

  关闭当前线程,类似于terminate。

  4.缓存:

  当前上下文的CacheStorage确保脱机可用性,并且可以定制请求的响应。

  5.控制台:

  支持控制台语法。

  6.导入脚本

  我们可以通过importScripts()方法在worker中通过url加载库函数。

  7.XMLHttpRequest

  有了它,您可以发出Ajax请求。

  8.您可以使用:

  SetTimeout/SetInterval AddEvent Listener/Postmessage有很多API可以用,这里就不举例了。

  八、异常处理

  当一个worker出现运行错误时,它的onerror事件处理程序将被调用。它将接收一个名为error的事件,该事件扩展了ErrorEvent接口。活动不会冒泡,可以取消。

  为了防止触发默认操作,工作线程可以调用错误事件的preventDefault()方法。

  错误我们常用以下三个关键信息:

  Message:可读的错误消息;Filename:发生错误的脚本文件的名称;Lineno:发生错误的脚本文件的行号;worker . on error=function(error){ console . log(error . message);投掷误差;};这就是本文的全部内容。希望对大家的学习和支持有帮助。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: