一.简单概述
webWorker是一种在后台运行脚本的浏览器功能
二.案例代码
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>hello world</div>
</body>
<script>
let worker = new Worker('http://localhost/webworker/worker.js', {type: 'module'})
worker.postMessage("hello world")
worker.addEventListener("message", e => {
console.log(e.data)
})
</script>
</html>
// worker.js
import {a1} from 'http://localhost/webworker/a.js'
console.log(a1);
self.addEventListener('message', function(e) {
self.postMessage('You said:' + e.data)
console.log(e.data);
})
// a.js
export function a1() {
console.log("a1");
}
三.总结特点
1.webWorker不能使用本地文件,必须是网络上的同源文件
const worker = new Worker('http://localhost/webworker/worker.js'); // 网络的同源文件
2.webWorker不能使用window上的dom操作,也不能获取dom对象,dom相关的东西只有主线程有。只能做一些计算相关的操作
// worker.js
console.log(window) // 报错:window is not defined
self.addEventListener('message', function(e) {
self.postMessage('You said:' + e.data)
console.log(e.data);
})
3.有的东西是无法通过主线程传给子线程,比如方法,dom节点,一些对象里的特殊设置(freeze,getter,setter这些,所以vue的响应式对象是不能传递的)
const worker = new Worker('http://localhost/webworker/worker.js')
worker.postMessage(()=>{
console.log("hello world");
}) // 不能传方法,会报错
4.模块的引入问题
(1)比如worker.js引入其他js(a.js),用importScripts
// a.js
function a1() {
console.log("a1");
}
// worker.js
importScripts("http://localhost/webworker/a.js"); // 必须是网络地址,但是这个地址可以跨域
console.log(a1);
(2)如果引入的js文件是esmodule规范的话,那么new Worker需要说明
// a.js
export function a1() {
console.log("a1");
}
// worker.js
importScripts("http://localhost/webworker/a.js");
console.log(a1); // 报错:Unexpected token 'export'
解决方法:new Worker的时候加type参数,worker.js用import引入方法
// 主线程
const worker = new Worker('http://localhost/webworker/worker.js', {type: 'module'})
// worker.js
import {a1} from 'http://localhost/webworker/a.js'
console.log(a1);