JavaScript多线程编程
栏目: JavaScript · 发布时间: 6年前
内容简介:浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,浏览器就会出现卡顿,降低了用户体验。为此,JavaScript提供了异步操作,比如定时器(setTimeout、setInterval)事件、Ajax请求、I/O回调等。我们可以把高负载的任务使用异步处理,它们将会被放入浏览器的事件任务队列(event loop)中去,等到JavaScript运行时执行线程空闲时候,
浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,浏览器就会出现卡顿,降低了用户体验。
为此,JavaScript提供了异步操作,比如定时器(setTimeout、setInterval)事件、Ajax请求、I/O回调等。我们可以把高负载的任务使用异步处理,它们将会被放入浏览器的事件任务队列(event loop)中去,等到JavaScript运行时执行线程空闲时候,事件队列才会按照先进先出的原则被一一执行。
nodejs引以为荣的异步处理
通过类似定时器,回调函数等异步编程方式在平常的工作中已经足够,但是如果做复杂运算,这种方式的不足就逐渐体现出来,比如settimeout拿到的值并不正确,或者页面有复杂运算的时候很容易触发假死状态,异步代码会影响主线程的代码执行,异步终究还是单线程,不能从根本上解决问题。
多线程(Web Worker)就应运而生,它是HTML5标准的一部分,这一规范定义了一套 API,允许一段JavaScript程序运行在主线程之外的另外一个线程中。将一些任务分配给后者运行。在主线程运行的同时,Worker(子)线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。
一、什么是web worker
worker是window对象的一个方法,可以通过以下方式来检测你的浏览器是否支持worker
if (window.Worker) {…… your code ……} 复制代码
一个worker是使用一个构造函数(Worker())创建的一个对象,这个构造函数需要传入一个的JavaScript文件,这个文件包含将在工作线程中运行的代码。类似于这样:
let myWorker = new Worker('worker.js'); 复制代码
worker通过postMessage() 方法和onmessage事件进行数据通信。主线程和子线程是双向的,都可以发送和监听事件。向一个worker发送消息需要这样做(main.js):
myWorker.postMessage('hello, world'); // 发送 worker.onmessage = function (event) { // 接收 console.log('Received message ' + event.data); doSomething(); } 复制代码
postMessage所传的数据都是拷贝传递(ArrayBuffer类型除外),数据子线程也是类似传递(worker.js)
addEventListener('message', function (e) { postMessage('You said: ' + e.data); }, false); 复制代码
当子线程运行结束后,使用完毕,为了节省系统资源,可以手动关闭子线程。如果worker没有监听消息,那么当所有任务执行完毕(包括计数器)后,它就会自动关闭。
// 在主线程中关闭 worker.terminate(); // 在子线程里线程 close(); // 监听 error 事件 worker.addEventListener('error', function (e) { console.log('ERROR', e); }); 复制代码
web worker本身很简单,但是它的限制特别多。
二、使用的问题
1、同源限制
分配给Worker 线程运行的脚本文件(worker.js),必须与主线程的脚本文件(main.js)同源。这里的同源限制包括协议、域名和端口,不支持本地地址(file://)。这会带来一个问题,我们经常使用CDN来存储js文件,主线程的worker.js的域名指的是html文件所在的域,通过new Worker(url)加载的url属于CDN的域,会带来跨域的问题,实际开发中我们不会吧所有的代码都放在一个文件中让子线程加载,肯定会选择模块化开发。通过 工具 或库把代码合并到一个文件中,然后把子线程的代码生成一个文件url。
解决方法:
(1)将动态生成的脚本转换成Blob对象。
(2)然后给这个Blob对象创建一个URL。
(3)最后将这个创建好的URL作为地址传给Worker的构造函数。
let script = 'console.log("hello world!");' let workerBlob = new Blob([script], { type: "text/javascript" }); let url = URL.createObjectURL(workerBlob); let worker = new Worker(url); 复制代码
2、访问限制
Worker子线程所在的全局对象,与主线程不在同一个上下文环境,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象,global对象的指向有变更,window需要改写成self,不能执行alert()方法和confirm()等方法,只能读取部分navigator对象内的数据。另外chrome的console.log()倒是可以使用,也支持debugger断点,增加调试的便利性。
3、使用异步
Worker子线程中可以使用XMLHttpRequest 对象发出 AJAX 请求,可以使用setTimeout() setInterval()方法,也可使用websocket进行持续链接。也可以通过importScripts(url)加载另外的脚本文件,但是仍然不能跨域。
三、应用场景
1、使用专用线程进行数学运算
Web Worke设计的初衷就是用来做计算耗时任务,大数据的处理,而这种计算放在worker中并不会中断前台用户的操作,避免代码卡顿带来不必要的用户体验。例如处理ajax返回的大批量数据,读取用户上传文件,计算MD5,更改canvas的位图的过滤,分析视频和声频文件等。worker中除了缺失了DOM和BOM操作能力以外,还是拥有非常强大的js逻辑运算处理的能力的,相当于nodejs一个级别的的运行环境。
2、高频的用户交互
高频的用户交互适用于根据用户的输入习惯、历史记录以及缓存等信息来协助用户完成输入的纠错、校正功能等类似场景,用户频繁输入的响应处理同样可以考虑放在web worker中执行。例如,我们可以 做一个像Word一样的应用:当用户打字时后台在词典中进行查找,帮助用户自动纠错等等。
3、数据的预取
对于一些有大量数据的前后台交互产品,可以新开一个线程专门用来进行数据的预取和缓冲数据,本地web数据库的行写入和更改,长时间持续的运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断,也有利于随时响应主线程的通信。也可以配合XMLHttpRequest和websocket进行不断开的通信,实现守卫进程。
四、兼容性
总体来说,兼容性还是不错的, 移动端可以放心使用,桌面端要求不高的话,也可以使用。
五、小结
对于web worker这项新技术,无论在PC还是在移动web,腾讯新闻前端组进行了广泛的使用,Web Worker 的实现为前端程序带来了后台计算的能力,可以实现主 UI 线程与复杂计运算线程的分离,从而极大减轻了因计算量大而造成 UI 阻塞而出现的界面渲染卡、掉帧的情况,并且更大程度地利用了终端硬件的性能。superWorker能解决掉事件绑定,同源策略的问题,它目前最大的问题在于不兼容IE9,在兼容性要求不是那么严格的地方,尽可能的使用吧!
《IVWEB 技术周刊》震撼上线了,关注公众号:IVWEB社区,每周定时推送优质文章。
周刊文章集合: weekly
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Java多线程编程核心技术(一)Java多线程技能
- JavaScript多线程编程
- Swift 多线程编程总结
- Java 并发编程基础 ① - 线程
- Java 多线程编程核心技术
- 使用openmp进行多线程编程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Design and Analysis of Distributed Algorithms (Wiley Series on P
Nicola Santoro / Wiley-Interscience / 2006-10-27 / USD 140.95
This text is based on a simple and fully reactive computational model that allows for intuitive comprehension and logical designs. The principles and techniques presented can be applied to any distrib......一起来看看 《Design and Analysis of Distributed Algorithms (Wiley Series on P》 这本书的介绍吧!