worker是干啥的?
我们知道 js 是单线程的,所有任务只能在一个线程上完成,一次只能做一件事。如果前面的任务没做完,后面的任务只能干等着。
Web Worker 可以为 js 提供多线程环境,允许主线程创建 Worker 线程,将一些任务分配给 Worker 来运行。
在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成任务,再把结果返回给主线程。
这样的好处是,一些计算密集型或高延迟的任务可以分担给 Worker 线程,主线程只负责 UI 交互,这样就会更加流畅,用户体验也会更好。
废话不多说,直接上代码。
index.html:
<!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>worker</title>
</head>
<body>
<div id="cont"></div>
</body>
</html>
<script>
let cont = document.getElementById('cont');
let worker = new Worker('1.js');
worker.onerror = (e) => {
console.log('error', e);
}
worker.postMessage({ username: 'jack', passwd: '123456' });
worker.onmessage = (ev) => {
console.log('接收到子线程的消息>>>', ev.data);
cont.innerText = ev.data;
}
</script>
1.js:
self.addEventListener('message',(e)=>{
console.log('接收主线程的消息',e.data);
//异步查询
setTimeout(()=>{
self.postMessage(`用户名:${e.data.username},密码:${e.data.passwd}`);//向主线程发送消息
},2000);
},false);
我们重点关注一下子线程的写法。
子线程的上下文 self 代表子线程自身,即子线程的全局对象,也可以写成 this ,或者干脆不写也行。
子线程脚本有一些使用方面的限制,比如无法使用document和window全局对象,不能使用alert()方法和confirm()方法等。
不过,子线程可以使用 XMLHttpRequest 对象,这样有一些延时较长的ajax查询可以丢到worker里面执行。
比如在某些h5项目中,启动页可以加载一个worker线程,将一些延时较长的预加载动作丢到里面处理。
网友评论