Web Worker无阻塞UI的牛逼技术,html5,可惜无法敢于UI
众所周知,JavaScript是单线程的,JS和UI更新共享同一个进程的部分原因是它们之间互访频繁,但由于共享同一个进程也就会造成js代码在运行的时候用户点击界面元素而没有任何响应这样的情况,这么糟糕的用户体验HTML5怎么会不修订了,这样Web Worker诞生了。
Web Worker进程加载的js运行的时候不仅不会影响浏览器UI,而且也不会影响其它Web Worker进程加载的JS代码。由于Web Worker进程加载的js运行的时候不会影响浏览器UI,也就说明Web Worker中加载的js不能修改用户界面,而每个Web Worker都有自己的全局运行环境,因为它加载的js不能修改用户界面,所以它能操作的对象主要只包括以下几个部分
- 一个浏览器对象,只包含四个属性:appName,appVersion,userAgent,platform
- 一个location对象(和window里的一样,但是里面所有的属性是只读的)
- 一个self对象指向全局Web Worker线程对象
- 一个importScripts()方法使Web Worker能够加载外部js文件
- 所有的ECMAScript对象
- XMLHttpRequest构造器
- setTimeout()和setInterval()方法
这里先特意讲一个importScript方法,它是以阻塞方法加载js的,只有所有文件加载完成之后接下来的脚本才能继续运行
事实上,Web Worker适合于那些纯数据的,或者说与浏览器UI没关系的长运行脚本。
下面附上最基本的demo事例,我相信聪明的你一看就会了
简单建立一个html页面,页面代码如下而所示
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> <script type="text/javascript"> var worker = new Worker("webworker.js"); //这句话将让浏览器去加载webworker.js worker.postMessage('主线程发起的数据请求!'); //把数据传递给webworker.js worker.onmessage = function (event) { console.log(event.data); //来自work的数据保存在event.data //接下来就可以对它event.data进行序列化等数据处理啦 }; </script> </body> </html>
上面代码加载的webworker.js的代码如下所示:
onmessage = function (event) { var data = event.data;//这是接收过来的数据 console.log(data);//注意啦 这里不能用alert来替换console.log 因为alert是会阻塞ui 所以wobworker没有使用alert的权限哦 postMessage(data + ' --- js回复过来的数据哦!');//这里可以把数据传递给主线程哦 }; onerror = function (event) { console.log('Error:' + event.filename + '(' + event.lineno + '):' + event.message); //event.filename 错误的文件名 //event.lineno 错误的行号 //event.message完整的错误消息 }
那么Web Worker的主要用处在哪儿呢,它的优点有哪些呢,下面总结一下哈
- 可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信,使用ternimate方法停止工作
- 可以在worker中通过importScripts(url)加载另外的脚本文件
它的主要缺点在哪儿呢
- 不能跨域加载JS
- worker内代码不能访问DOM
- 因为它是html5中新的API,所以各个浏览器支持都不一样哦!
web worker来加载数据还是比较慢的,即便是大数据量情况下也没任何优势,可能是Worker初始化新起线程比较耗时间。除了在加载过程中是无阻塞的之外没有任何优势
下面再附上我写的一个例子,主要是发挥Web Worker的特长
html界面代码如下所示
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> <script type="text/javascript"> var worker = new Worker('fibonacci.js'); worker.addEventListener('message', function (event) { console.time('总共花费的时间为:'); console.log('结果:' + event.data); console.timeEnd('总共花费的时间为:'); }, false); worker.postMessage(40); </script> </body> </html>
上面代码中加载的fibonacci.js代码如下所示
var fibonacci = function (n) { return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2); }; onmessage = function (event) { var n = parseInt(event.data, 10); console.log('传过来的值为:'+n); postMessage(fibonacci(n)); }; onerror = function (event) { console.log('Error:' + event.filenme + '(' + event.lineno + '):' + event.message); }
大家运行后可以发现chrome控制台的结果如下图所示:
——————————————————————————————————————————————————————
下边这个例子比较经典:
main.html页面为主线程
<script>
//开辟一个新线程
var worker = new Worker('worker.js');
worker.postMessage(40) ;
worker.onmessage = function(ev){
console.log(ev);
worker.terminate() //终止一个worker线程
};
</script>
worker.js 开辟的新线程
//新线程
//定义递归函数
var fibonacci =function(n) {
return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
};
onmessage = function(ev){
var param = parseInt(ev.data,10) ;
//把地柜函数的计算交给新线程,计算完之后用postMessage把结果传回给主线程
postMessage(fibonacci(param))
}
这样就可以实现主线程和新开辟的线程之间的信息交互。复杂的计算就交给了worker.js。页面不用卡死。新线程会在处理完计算之后把数据传回给主线程(有点异步请求的感觉)。
总结我们
Web Worker无阻塞UI的牛逼技术,html5,可惜无法敢于UI的更多相关文章
- 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密
下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问 ...
- 来自牛逼哥的阴间MD5(web)
这个web题目是来自队里面牛逼哥的题目,审计源码, 看到这两个参数,前面的a和b就是直接输出数字,再看下面的,需要弱比较的输出一个c,要求应该是需要一个加密之前是一个0e开头的字符串,加密之后还是0e ...
- Web Worker
写在前面 众所周知,JavaScript是单线程的,JS和UI更新共享同一个进程的部分原因是它们之间互访频繁,但由于共享同一个进程也就会造成js代码在运行的时候用户点击界面元素而没有任何响应这样的情况 ...
- 无阻塞加载js,防止因js加载不了影响页面显示
浏览器加载静态资源和js的方式都是线性加载,所以一般情况可以将js放到</body>前,防止UI线程的阻塞. 而某些时候我们既希望js在整个网页的头部就加载,又担心js阻塞导致网站加载缓慢 ...
- js同步、异步、延时、无阻塞加载
一.同步加载 平常默认用的都是同步加载.如:<script src="http://yourdomain.com/script.js"></script> ...
- web worker原理 && SSE原理
第一部分 什么是 web worker? 我们一直强调JavaScript是单线程的,但是web worker的出现使得JavaScript可以在多线程上跑,只是web worker本身适合用于一些复 ...
- HTML5 Web Worker的使用
Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker Web Wo ...
- 深入理解JS异步编程四(HTML5 Web Worker)
>Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker We ...
- 通过一次实验来了解HTML5的 Web Worker
web worker 是运行在后台的 JavaScript,不会影响页面的性能. 当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成. web worker 是运行在后台的 Ja ...
随机推荐
- javascript 巴西世界杯倒计时
巴西世界杯是足球迷的今年最终关注的事情,做为球迷的我也不例外,自己做了一个巴西世界杯的倒计时. <!DOCTYPE html> <html> <head> < ...
- Laravel邮件发送问题小解
在Laravel中已经有内置了发送邮件的功能,通过 Mail::send 可发送邮件,但要使用这个函数必须先进行相关配置. 在 /app/config/mail.php 中设置你的邮件参数,如下: 1 ...
- dsp与dmp的cookie mapping
dsp ad.com 在 meijiu.com上部署广告. 假设dmp叫cm.api.taobao.com 建立gid映射表 (1) ad.com在meiju.com的页面上部署,指向dmp ...
- S3C2440看门狗解析
个PCLK周期的复位信号 也就是说,在某些环境下,看门狗可以当做定时器使用,当他中断的时候并不发生复位,只发生中断,我看看图 看门狗的中断和复位信号是可以依靠wtcon来切断的(看门狗的时钟是无法切断 ...
- 菊花加载第三方--MBprogressHUD
上次说到了网络请求AFN,那么我们在网络请求的时候,等待期间,为了让用户不认为是卡死或程序出错,一般都会放一个菊花加载,系统有一个菊花加载类叫UIProgressHUD.但是我今天要说的是一个替代它的 ...
- 如何获得keyhash
keyhash是由keystore产生的 三个命令解决问题 keytool -exportcert -alias androiddebugkey -keystore debug.keystore &g ...
- AngularJS 讲解,四 Directive
AngularJS Directive 自定义指令(我最喜欢AngularJs的功能之一) 一:什么时候我们会用到directive 1.使html更具语义化,不用深入了解研究代码的逻辑便可知道大致 ...
- python实现断点续传下载文件
最近的任务里有一个功能是要我从日志服务器实时跟新日志到本地,日志在不断新增内容就需要我隔一段时间从上次下载的位置继续下载,并写入本地文件上次写完的位置后面. headers = {'Range': ' ...
- Android与JNI(二) ---- Java调用C++ 动态调用
目录: 1. 简介 2. JNI 组件的入口函数 3. 使用 registerNativeMethods 方法 4. 测试 5. JNI 帮助方法 6. 参考资料 1. 简介 Android与JNI( ...
- App外包开发周期一般多长?
很多人问我,开发一个app要用多长时间.事实上开发一款app没有固定周期的,得因产品而论,你软件的功能需求决定了app外包开发的周期.但是除了app本身以外,人为因素往往对开发周期也有一定的影响.例如 ...