众所周知,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的更多相关文章

  1. 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密

    下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问 ...

  2. 来自牛逼哥的阴间MD5(web)

    这个web题目是来自队里面牛逼哥的题目,审计源码, 看到这两个参数,前面的a和b就是直接输出数字,再看下面的,需要弱比较的输出一个c,要求应该是需要一个加密之前是一个0e开头的字符串,加密之后还是0e ...

  3. Web Worker

    写在前面 众所周知,JavaScript是单线程的,JS和UI更新共享同一个进程的部分原因是它们之间互访频繁,但由于共享同一个进程也就会造成js代码在运行的时候用户点击界面元素而没有任何响应这样的情况 ...

  4. 无阻塞加载js,防止因js加载不了影响页面显示

    浏览器加载静态资源和js的方式都是线性加载,所以一般情况可以将js放到</body>前,防止UI线程的阻塞. 而某些时候我们既希望js在整个网页的头部就加载,又担心js阻塞导致网站加载缓慢 ...

  5. js同步、异步、延时、无阻塞加载

    一.同步加载 平常默认用的都是同步加载.如:<script src="http://yourdomain.com/script.js"></script> ...

  6. web worker原理 && SSE原理

    第一部分 什么是 web worker? 我们一直强调JavaScript是单线程的,但是web worker的出现使得JavaScript可以在多线程上跑,只是web worker本身适合用于一些复 ...

  7. HTML5 Web Worker的使用

    Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker Web Wo ...

  8. 深入理解JS异步编程四(HTML5 Web Worker)

    >Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker We ...

  9. 通过一次实验来了解HTML5的 Web Worker

    web worker 是运行在后台的 JavaScript,不会影响页面的性能. 当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成. web worker 是运行在后台的 Ja ...

随机推荐

  1. mysql 二级索引

    mysql中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(secondary indexes). 以InnoDB来说,每个Inn ...

  2. spring 5种通知

    方法实现接口 package com.cn.spring.aop.impl; //加减乘除的接口类 public interface ArithmeticCalculator { int add(in ...

  3. SD卡兼容性问题(转)

    看到一篇关于硬件抗干扰的应用实例,很有参考值.所以,转过来方便查找. 源文:SD卡兼容性问题 最近碰到了一个SD卡兼容性的问题.主芯片SD卡组的信号,经过转接板,长排线,然后再到SD卡子板之后.对多种 ...

  4. iOS开发中涉及的字体问题

    iOS中常见3种方法来控制字体,下面根据我在网上学习总结的内容发布(已完美避过所有坑,iOS8.4) 一.系统默认的设置字体方法(只对英文和数字生效的方法) 1.系统默认提供的字体主要是指UIFont ...

  5. STL中list用法

    本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到普通函数,而且例子丰富,通俗易懂.不失为STL的入门文章,新手不容错过! 0 前言 1 定义一个list 2 使用list的成员函 ...

  6. 【转】amCharts,一款值得推荐的Flash charts图组件

    今天无意中看到一个利用Flash生成chart图的工具:amCharts,我一开始就觉得这些chart图非常眼熟,它的显示样式跟监控宝的是完全一样的,我通过查看网页的源文件,才知道原来监控宝就是用的这 ...

  7. dom4j生成和解析xml文件

    dom4j生成和解析xml文件 要生成和解析如下格式的xml文件: <?xml version="1.0" encoding="UTF-8"?> & ...

  8. Zend Framework Module之多模块配置

    摘要:该文将为大家简单介绍一下如何使用zend framework创建模块化的应用程序. zend framework对多模块的支持是很好的,但是可能是由于功能太过强大的缘故,部署起来并不是很容易.许 ...

  9. ubuntu 16.04 php 安装curl方法

    先查看自己的php是否已经安装了curl.方法如下:1.在web服务器目录( Ubuntu下的通常为 /var/www )新建test.php文件2.编辑文件,键入下面一行代码:<?php ph ...

  10. UVa 336 - A Node Too Far

    题目大意:在计算机网络中,每条信息都有一个TTL值,在信息到达一个节点时,TTL值首先减1,如果TTL为0,则丢弃该信息报文.给一个网络的配置,给定源点和TTL值,判断该网络中有多少节点不可到达. 无 ...