web worker 是运行在后台的 JavaScript,不会影响页面的性能。
当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。
web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 在后台运行。
以上是W3School对WebWorker的定义,讲的非常明确。在这段解释中,我一眼就看到了一句话“执行脚本时,页面状态是不可响应的”,这让我想到了BOM的一些系统对话框,像alert之类的。大家都知道当有alert之类的消息窗口时,它是模态且同步的,整个HTML页面元素和脚本都会停止无法点击,直到点击了确定,脚本才会继续执行。如果按照HTML5的Web Worker的后台工作的性质,是否意味着可以不受限于对话框的限制,继续执行代码。本着实践出真知,下面一起来看看!
1. 我们首先看看正常情况,一个自动累加器是如何运作的。
第一张图,附上HTML结构。我们是用一个非常常见的方法,也就是通过一个setTimeout定时器,不断重复调用自身,达到1S增加一次的效果。然后把累加的值,放到output标签内。然后我们让它跑起来吧!
我们可以发现,当我们点击alert按钮的时候,数字不再往上累加。这是我们非常常见的啦,因为对话框是同步执行的,意味着不点击就会造成线程阻塞。难不成用了Web Worker就可以继续运行?我们接下来继续看。
2. 使用Web Worker的累加器。
在我们看运行的GIF之前,我们先看看如何构建一个Web Worker。
首先,我们需要检测一下浏览器是否支持Worker,毕竟是一个HTML5的新功能。然后直接通过new一个Worker,再把需要执行的脚本文件作为一个参数传进去。然后通过监听这个Web Worker的message事件,数据放在event.data进行实时的反馈。既然有一个message事件,那么那个需要执行的脚本自然会有一个发送message的操作,我们看一下是什么样子的。
也就是postMessage(data),通过这个API我们可以将Worker里的数据通过message传出去。然后外部再监听message事件,进行数据更新。那说了这么多,那真正的问题是否解决了呢?也就是那个,Worker里执行的脚本是独立于其它脚本,自行在后台运行的。废话不多说,直接看效果!
非常的牛逼!我忍不住打了几个字。我们可以清楚的看到,对于单线程的JavaScript来说,即使模态框阻塞了线程,计数器的数字依旧是在做改变的。(这里不得不有些小疑问,既然线程被阻塞了,但是为什么message事件监听触发的innerHTML依旧是可以运行?难道是只要事件一触发就会立即执行的原因?有知道的人可以帮忙解答一下,谢谢~!)从这里我们可以明显看到,确实在web worker的Js脚本是独立的,并不会和当前页面的脚本相冲突。当然,这里不得不提一句,Web Worker的Js脚本的作用域和当前页面Js脚本作用域并不能共享,换言之也就是,它们的全局作用域并不是同一个,Worker的全局作用域是它自己本身,所以Web Worker自然也就无法操作DOM元素。
那我们可以用 Web Worker 做什么呢?因为Js的单线程,我们必须要防止过大的计算堵塞了用户页面,那通过这个HTML5最新的 Web Worker 技术,我们可以把一些非常耗时的计算都放在外部,以免影响了用户体验。
最后,这里同样是抛砖引玉。希望可以通过这个可以帮助更多的人,了解到较新的HTML5技术,然后主动的去探寻更多的Web技术。