浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,浏览器就会出现卡顿,降低了用户体验。

为此,JavaScript提供了异步操作,比如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 的实现为前端程序带来了后台计算的能力,可以实现主 UI 线程与复杂计运算线程的分离,从而极大减轻了因计算量大而造成 UI 阻塞而出现的界面渲染卡、掉帧的情况,并且更大程度地利用了终端硬件的性能。superWorker能解决掉事件绑定,同源策略的问题,它目前最大的问题在于不兼容IE9,在兼容性要求不是那么严格的地方,尽可能的使用吧!

js多线程编程web worker相关推荐

  1. android 多线程 js,JS多线程(web work)

    JS多线程 JS多线程不允许操作DOM 1. 引用Concurrent Thread.js库 用法:Concurrent.Thread.Create(function(){};) 2. Web Wor ...

  2. js多线程的实现-Worker

    大家都知道js是基于单线程的,而这个线程就是浏览器的js引擎. 首先来看一下大家用的浏览器都具有那些线程吧. 如果我们要执行一些耗时的操作,比如加载一张很大的图片,我们可能需要一个进度条来让用户进行等 ...

  3. 原生JS多线程解决方案:Worker

    一.简介 一般情况下我们使用JS都是单线程的模式,也就是前边的代码执行完,才能轮到后边的代码执行.后来因为电脑计算能力的增强,单线程模式对于多核CPU的计算机计算能力便出现了一些浪费. web Wor ...

  4. 如何查找历史线程阻塞原因_学习 Web Worker(js中的“多线程”)

    昨天部门例会,讨论开发的系统遇到的问题,遇到一个医保上传比较耗时的问题,解决方案提到了Web Worker,学习一波. 首先简单介绍一下什么是web worker.我们都知道在浏览器中javascri ...

  5. web worker实现一个简单的异步编程

    文章目录 一.前言 二.一个案例 三.web worker解决 四.执行原理 五.线程和进程 六.其他 一.前言 假设一个场景,你的后端是个小白,你需要自己实现一个十万数量级的数据处理(当然这是不可能 ...

  6. web worker使用

    JavaScript的一个特性就是单线程,web worker的出现解决了JavaScript无法多线程的问题,定义了"Worker"来执行代码的并行线程. web worker有 ...

  7. web worker介绍以及应用场景

    web worker介绍以及应用场景 什么是web worker ? 为什么要用web worker ? 怎么使用web worker ? 1.主线程采用new 命令,调用worker构造函数,Wor ...

  8. web Worker简介、web Worker报错分析、作用

    web Worker: web Worker是运行在后台的javascript,不会影响性能,常用于高耗费CPU的任务,必须部署到线上才可以正常使用,这里有三个方法比较重要,需要注意: postMes ...

  9. 深入理解javascript异步编程障眼法h5 web worker实现多线程

    0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 1 2 3 4 ...

  10. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

最新文章

  1. adc0832对光电二极管进行数据采集_实车采集的现场数据如何导入控制模型进行分析...
  2. 解决eureka注册时使用ip而不是hostname
  3. android listview下拉动画效果,Android开发中利用ListView实现一个渐变式的下拉刷新动画...
  4. openmp 互斥锁 mysql_openMP 函数总结(并行程序设计导论)
  5. php连接excel表格数据类型,TP5 中使用PHPExcel 导出导入数据到excel表格
  6. JSON之Asp.net MVC C#对象转JSON,DataTable转JSON,ListT转JSON,JSON转ListT,JSON转C#对象...
  7. python对文件操作方法是_Python文件操作
  8. 疯狂Java讲义笔记汇总
  9. ARM存储器控制器的使用
  10. C语言 简单实现计算器功能 ·函数指针数组实现计算器
  11. 纯色图制作APP代码
  12. 记一次艰苦的刷机历程,nexus7 刷cm12 nightly版,刷入gapps
  13. iOS 将状态栏设置成白色
  14. 7-28 天梯赛的善良 (PTA C语言)最简
  15. matlab 热图,基于表格数据创建热图
  16. 蓝桥杯:试题 算法训练 采油区域 矩阵前缀和+动态规划+分治+枚举
  17. 2021年安全员-B证(广西省)作业考试题库及安全员-B证(广西省)模拟考试题库
  18. 【从入门到精通 项目1】项目经理带你-零基础学习C/C++
  19. 试卷代号:49242021年春季学期期末统一考试农业经济基础 试题
  20. 【身份证识别】基于形态学实现ID号码识别系统matlab源码含GUI

热门文章

  1. Python 文件,文件读取一行(readline)
  2. 两种操作botton的方法
  3. 关于高通8953修改动态logo bootanimation不起作用问题
  4. 闲鱼的排名规则是什么,闲鱼排名规则方法?
  5. Power BI 客户端 安装 错误
  6. 使用DISM修复系统
  7. 领域驱动设计实践(战术篇)
  8. #Excel公式应用#从数据透视表进一步汇总文本信息
  9. ssh-keygen认证密钥
  10. Windows10远程桌面登录——Teamviewer