web worker
在浏览器中,js是单线程执行的,对于数据量大的处理会引起页面的卡顿以及浏览器的假死;web workder 可以理解为在js主线程中一个独立运行环境实体;web worker 允许把主线程需要执行的操作转接给web worker 让web woker 来执行处理数据量大的操作,在这个操作过程中,页面不会卡顿,能有较好的用户体验.
实际运用
- 当页面需要执行数据量大的处理(这里使用for循环来制造卡顿)
function accumulation(){
let count = 0;
for(let i = 0;i<999999999999999;i++){
count += i;
}
return count;
}
- 上面函数执行会有相应的计算过程,计算过程中页面是不能够进行一个交互的.这时引入
web worker 能有效的解决这个问题;
//main.js
//1 使用脚本创建 web worker
cont worker = new Worker('https://woker.js');
//2 需要执行计算时,向web worker 发送执行信息
worker.postMessage({msg:"执行"});
//5 监听web worker的消息
worker.addEventListener('message',(e)=>{
const { reslut } = e.data;
//获取到了 计算结果
console.log(reslut);
})
3.将计算的代码放在web worker 中执行,当web worker 接受到信息执行计算操作
//woker.js
function accumulation(){
let count = 0;
for(let i = 0;i<999999999999999;i++){
count += i;
}
return count;
}
//3 监听message事件,接受到信息后,获取到接受到的信息,执行相应的操作
self.addEventListener('message',(e)=>{
const { msg } = e.data;
if(msg === "执行"){
const result = accumulation();
//4 计算完成后通过消息将计算结果返回给主线程
self.postMessage({result})
}
})
web worker的注意事项
- 同源限制:分配给web worker 线程运行的脚本文件,必须与主线程文件同源
- DOM限制:worker线程所在的全局对象,无法读取主线程所在页面的DOM对象.也无法使用document,window,parent这些对象,但是worker线程中可以访问nacigator对象和location对象
- 通信联系:worker线程和主线程不在同一个上下文环境,他们不能直接通信,必须通过消息通信
- 脚本限制:worker不能执行alert,confirm方法,但是可以使用xmlHttpRequest对象发送ajax请求
- 文本限制: worker 线程无法读取本地文件,即不能打开本地的文件系统,它所加载的脚本必须来自网络
使用字符串使用web woker
//1 将要在web worker 执行的代码存为字符串
const data = `
function accumulation(){
let count = 0;
for(let i = 0;i<999999999999999;i++){
count += i;
}
return count;
}
//3 监听message事件,接受到信息后,获取到接受到的信息,执行相应的操作
self.addEventListener('message',(e)=>{
const { msg } = e.data;
if(msg === "执行"){
const result = accumulation();
//4 计算完成后通过消息将计算结果返回给主线程
self.postMessage({result})
}
})
`;
//2 生成二进制 数据 Blob
const blob = new Blob([data]);
//2 生成 url
const url = window.URL.createObjectURL(blob);
//3 使用url 生成web worker
const worker = new Worker(url);
...
完整代码
<!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>
</head>
<body>
<script>
const data = `
function accumulation(){
let count = 0;
for(let i = 0;i<99999999999;i++){
count += i;
}
return count;
}
//3 监听message事件,接受到信息后,获取到接受到的信息,执行相应的操作
self.addEventListener('message',(e)=>{
const { msg } = e.data;
console.log('接受到了消息,执行中');
if(msg === "执行"){
const result = accumulation();
//4 计算完成后通过消息将计算结果返回给主线程
console.log('计算完成,返回计算结果');
self.postMessage({result})
}
})
`;
//生成 blob
const blob = new Blob([data]);
//生成 url
const url = window.URL.createObjectURL(blob);
//生成web worker
const worker = new Worker(url);
worker.addEventListener('message',(e)=>{
const result = e.data.result;
console.log(result);
});
worker.postMessage({msg:"执行"});
</script>
</body>
</html>