介绍
Web Workers 是HTML5提供的一个javaScript多线程解决方案。我们可以将一些大计算量的代码交给Web Workers运行而不冻结用户界面。但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变javaScript单线程的本质。

使用
背景:假设页面中有一个输入框,根据用户输入数值,来计算相应的斐波那契数列的结果。当输入的值比较大的时候,计算需要的时间非常长,而且页面被冻结不能进行其他操作。这时候我们希望能把计算放到分线程去执行,不影响主线程页面操作。
<!DOCTYPE html>
<html lang="en">
<body>
<input type="text" placeholder="请输入数值" id="number" />
<button id="btn">计算</button>
<script>
var input = document.getElementById('number')
document.getElementById('btn').onclick = function() {
var number = input.value
// 创建一个worker对象
var worker = new Worker('worker.js') // 接收一个分线程文件地址
// 绑定接收消息的监听
worker.onmessage = function(event) {
// 通过event.data接收数据
console.log('主线程接收分线程返回的数据:' + event.data)
alert(event.data)
}
// 向分线程发送消息
worker.postMessage(number)
console.log('主线程向分线程发送数据:' + number)
}
</script>
</body>
</html>
写一个分线程js文件,把大量计算的逻辑写到这里
// server.js
function fibonacci(n) {
return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2)
}
// 固定写法
var onmessage = function(event) {
var number = event.data
console.log('分线程接收到主线程发送的数据:' + number)
// 计算
var result = fibonacci(number)
postMessage(result)
console.log('分线程向主线程返回数据:' + result)
// alert(result) alert是window的方法,在分线程不能调用
// 分线程中的全局对象不再是window, 所以在分线程中不可能更新界面
}

分线程中的this不再是window,而是下面的这个对象,所以分线程中不能操作页面。

Web Workers的局限
- 同源限制(不支持跨域)
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。 - DOM 限制(不能访问DOM)
Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以使用navigator对象和location对象。 - 通信联系
Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息Worker.postMessage()
完成。 - 脚本限制
Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。 - 文件限制
Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。
注意点
-
Worker 线程无法读取本地文件
直接在浏览器打开html文件会出现下面的报错:
image.png
可以用webpack等开启一个本地服务器,然后在浏览器上访问。
网友评论