前言
在工作中有时候需要用到大量数据的计算,那么由于JS是单线程的,在计算数据时就会阻塞页面的渲染导致有很长的白屏时间,看起来就好像卡死了一样。 这时我们就可以使用Web Worker开辟一个独立于主线程的子线程来进行这些数据计算
在HTML中使用
在主线程中使用new Worker来创建Web Worker
const worker=new Worker(aURL, options)
它有两个参数:
- aURL(必须)是一个DOMString 表示worker 将执行的脚本的URL。它必须遵守同源策略。
- options (可选)它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程
在主线程中使用postMessage来发送数据,onmessage接收数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<h1 id="btn">Click Me</h1>
</head>
<body>
<script>
const Woker = new Worker("./woker.js")
Woker.postMessage(5000000000);
Woker.onmessage = (e) => {
console.log(111, e.data);
};
</script>
</body>
</html>
在子线程中收发消息:
self.onmessage = e => {};
or:
self.addEventListener('message', function (e) {
console.log(e.data)
}, false);
self.postMessage("...");
self.addEventListener('message', function (e) {
let num = e.data;
console.log(num)
for (let i = 0; i <= num; i++) {
if (i == num) {
//2.向主线程发送数据
console.log('finished')
self.postMessage('任务完成啦!')
}
}
}, false);
在Vue中使用
注意事项:
- 安装worker-loader
- 在vue.config.js中作配置:
chainWebpack: config => { config.module.rule('worker').test(/\.worker\.js$/).use('worker-loader').loader('worker-loader').options({ inline: 'fallback' }) }, - worker文件要使用xxx.worker.js命名
<script>
import Woker from "./web5.worker.js";
export default {
mounted() {
let ul = document.getElementById("container");
const W = new Woker()
W.postMessage(100000)
W.onmessage = (e) => {
console.log(e.data)
ul.innerHTML = (fragment);
}
};
</script>
self.addEventListener('message', function (e) {
let num = e.data;
let fragment = ''
for (let i = 0; i < num; i++) {
let li = `<li>${i}</li>`;
fragment += li
}
self.postMessage(fragment)
}, false);
效果对比
使用Web Worker前:
使用Web Worker后:
可以清晰的看到,使用了Web worker后就不会再阻塞页面的渲染了