JS SharedWorker介绍/广播/Vue使用
- 一、SharedWorker介绍
- 二、SharedWorker使用
- 1、兼容性
- 2、创建
- 3、通讯
- 4、启动和关闭
- 5、调试
- 6、最简单demo
- 6.1 SharedWorker.js 代码
- 6.2 Page1.html 代码
- 6.3 Page2.html 代码
- 6.4 结果输出
- 三、SharedWorker使用注意项
- 四、广播示例
- 4.1 SharedWorker.js 代码
- 4.2 Page1.html 代码
- 4.3 Page2.html 代码
- 4.4 结果输出
- 五、vue中使用
- 5.1 建立子共享线程js
- 5.2 vue文件使用
一、SharedWorker介绍
SharedWorker是Worker中的一种,中文名叫’共享线程‘,主要用于同源页面之间的共享线程和数据,常用于浏览器不同标签页面之间进行通讯。
如果还不了解Worker,可以查看这里。
二、SharedWorker使用
1、兼容性
ie不支持,chrome完全支持
兼容性判断:if (!SharedWorker) { throw new Error('当前浏览器不支持SharedWorker') }
2、创建
- 创建共享线程的js文件:SharedWorker.js
- 创建共享线程
const worker = new SharedWorker('SharedWorker.js')
- 每创建一个worker,如果参数url都一样,那么会视为使用同一个共享线程,共享线程会分配一个端口port来区分不同使用者
3、通讯
- 主线程和共享线程都是通过
postMessage()
方法来发送消息 - 接收消息都是使用
onmessage = (e)=>{}
,或者addEventListener('message', (e)=>{})
4、启动和关闭
线程通过 worker.port.start()
启动
线程通过 worker.port.close()
关闭
使用单页应用的时候记得关闭,否则常驻
5、调试
SharedWorker不能直接在页面调试面板查看,需要浏览器输入 chrome://inspect/#workers
然后点击inspect查看
6、最简单demo
这里使用最简单的demo来说明使用方式,
- SharedWorker.js 共享线程,里面存储计时器counter
- page1.html 刷新页面,通知counter+1
- page2.html 刷新页面,查看counter
6.1 SharedWorker.js 代码
// 计时器
let counter = 0
// 监听连接
self.addEventListener('connect', (e) => {
const port = e.ports[0]
port.onmessage = (res) => {
console.log('共享线程接收到信息:', res.data)
switch (res.data) {
case 'counter++':
counter++
break
}
console.log('counter:', counter)
port.postMessage(counter)
}
})
6.2 Page1.html 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SharedWorker示例-页面1</title>
</head>
<body>
<h1>SharedWorker示例-页面1</h1>
<script>
// 兼容性判断
if (!SharedWorker) {
throw new Error('当前浏览器不支持SharedWorker')
}
// 创建共享线程
const worker = new SharedWorker('SharedWorker.js')
// 启动线程端口
worker.port.start()
// 向共享线程发送消息
worker.port.postMessage('counter++')
// 线程监听消息
worker.port.addEventListener('message', (e) => {
console.log('page1页面共享线程counter值:', e.data)
})
</script>
</body>
</html>
6.3 Page2.html 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SharedWorker示例-页面2</title>
</head>
<body>
<h1>SharedWorker示例-页面2</h1>
<script>
// 兼容性判断
if (!SharedWorker) {
throw new Error('当前浏览器不支持SharedWorker')
}
// 创建共享线程
const worker = new SharedWorker('SharedWorker.js')
// 启动线程端口
worker.port.start()
// 向共享线程发送消息
worker.port.postMessage('get counter')
// 线程监听消息
worker.port.addEventListener('message', (e) => {
console.log('page2页面共享线程counter值:', e.data)
})
</script>
</body>
</html>
6.4 结果输出
三、SharedWorker使用注意项
SharedWorker是Worker的一种应用,所以注意项和Worker一致
- 共享线程的上下文为自身,可以通过self,或者this来获取;
- 主线程和共享线程之间传递的消息是复制而不是共享,也就是说如果传递参数是一个对象,那么程序会使用JSON方式来编码/解码对象;
- 主线程和子线程是不同上下文,不同作用域,子线程不能调用主线程的dom和方法,具体
不能使用:
- window 对象
- document 对象
- parent 对象
- alert()
- confirm()
可以使用:
- navigator 对象
- location 对象(只读)
- XMLHttpRequest
- setTimeout()/clearTimeout() 和 setInterval()/clearInterval()
- 应用缓存
- 使用 importScripts() 方法导入外部脚本
- 生成其他 Web Worker
四、广播示例
上面的demo只演示了不同页面共用了共享线程的数据,但刷新page1并不会主动通知page2数据变更,page2必须刷新才能获取新数据,那么如果实现广播效果呢?
下面demo实现广播效果,即 共享线程会向所有端口发送消息
- SharedWorker.js 共享线程,存储计时器counter,counter变更会通知page1和page2
- page1.html 刷新页面,通知counter+1
- page2.html 刷新页面,通知counter+1
4.1 SharedWorker.js 代码
核心在于把所有连接的端口存起来
let counter = 0 // 计时器
let ports = [] // 存储所有连接端口的数组
// 监听连接
self.addEventListener('connect', (e) => {
const port = e.ports[0]
// 把端口对象存起来
ports.push(port)
// 监听消息
port.onmessage = (res) => {
console.log('共享线程接收到信息:', res.data)
switch (res.data) {
case 'counter++':
counter++
break
}
console.log('当前counter:', counter)
// 向所有端口广播
ports.forEach((p) => {
p.postMessage(counter)
})
}
})
4.2 Page1.html 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SharedWorker示例-页面1</title>
</head>
<body>
<h1>SharedWorker示例-页面1</h1>
<script>
// 兼容性判断
if (!SharedWorker) {
throw new Error('当前浏览器不支持SharedWorker')
}
// 创建共享线程
const worker = new SharedWorker('SharedWorker.js')
// 启动线程端口
worker.port.start()
// 向共享线程发送消息
worker.port.postMessage('counter++')
// 线程监听消息
worker.port.addEventListener('message', (e) => {
console.log('page1页面共享线程counter值:', e.data)
})
</script>
</body>
</html>
4.3 Page2.html 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SharedWorker示例-页面2</title>
</head>
<body>
<h1>SharedWorker示例-页面2</h1>
<script>
// 兼容性判断
if (!SharedWorker) {
throw new Error('当前浏览器不支持SharedWorker')
}
// 创建共享线程
const worker = new SharedWorker('SharedWorker.js')
// 启动线程端口
worker.port.start()
// 向共享线程发送消息
worker.port.postMessage('counter++')
// 线程监听消息
worker.port.addEventListener('message', (e) => {
console.log('page2页面共享线程counter值:', e.data)
})
</script>
</body>
</html>
4.4 结果输出
五、vue中使用
5.1 建立子共享线程js
建立共享线程js:根目录/public/shared-worker/SharedWorker.js
,代码如下:
// 计时器
let counter = 0
// 监听连接
self.addEventListener('connect', (e) => {
const port = e.ports[0]
port.onmessage = (res) => {
console.log('共享线程接收到信息:', res.data)
switch (res.data) {
case 'counter++':
counter++
break
}
console.log('counter:', counter)
port.postMessage(counter)
}
})
5.2 vue文件使用
建立vue文件,代码如下
<template>
<div><h1>SharedWorker使用</h1></div>
</template>
<script>
export default {
created() {
// 兼容性判断
if (!window.SharedWorker) {
throw new Error('当前浏览器不支持SharedWorker')
}
// 创建共享线程
this.worker = new SharedWorker('/shared-worker/SharedWorker.js')
// 启动线程端口
this.worker.port.start()
// 向共享线程发送消息
this.worker.port.postMessage('counter++')
// 线程监听消息
this.worker.port.addEventListener('message', this.messageHandle)
},
methods: {
// 消息处理
messageHandle(e) {
console.log('SharedWorker共享线程counter值:', e.data)
},
},
destroyed() {
// 记得销毁线程
this.worker.port.removeEventListener('message', this.messageHandle)
this.worker.port.close()
this.worker = null
},
}
</script>
兄弟,都看到这里了,点个赞再走呗