Web worker的使用
JavaScript是单线程语言,一些复杂的计算操作不能在主线程运行,不然就会造成卡顿,响应时间长。而Web worker 是运行在后台的 JavaScript,不会影响页面的性能。为JavaScript创建多线程,允许主线程创建Worker线程,这样就可以将一些复杂的运算交给Worker线程运行,不会给主线程造成阻塞。
什么是Web worker?
官方解释: 当在 HTML 页面中执行脚本时,页面是不可响应的,直到脚本已完成。Web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 运行在后台。
Web worker主要注意的地方
- Web Worker无法访问DOM节点;
- Web Worker无法调用alert()或者confirm之类的函数
- Web Worker无法使用document、window、parent这些对象
- Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
Web worker实现
这里的应用场景是在worker线程轮询一个方法,Worker()构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。
// An highlighted block
let webWork;
// 轮询
// timeStampIp 时间戳 参数 根据自己定义
function goWebWorker(timeStampIp) {
if (typeof (Worker) !== "undefined") { // 检测用户的浏览器是否支持
webWork = new Worker('../../js/workQRGotoHome.js'); // Worker()构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。
let conent = {};
conent.key = timeStampIp;
conent.abp = abp.security.antiForgery.getToken();
webWork.postMessage(conent); // 向worker线程发送信息
webWork.onmessage = function (event) { // 监听接收子线程的消息
console.log('Received message ' + event.data);
// doSomething();
}
}
}
workQRGotoHome.js 文件在项目的位置
workQRGotoHome.js 里面执行的方法
// 轮询,判断redis是否有key对应的数据, 有就页面跳转
function findForver() {
var key;
let timer = null;
self.addEventListener('message', function (e) {
console.log('子线程', e.data)
if (e.data.mag) {
this.clearTimeout(timer);
} else {
var data = { key: e.data.key };
function fetchKey() {
fetch('/Account/VisitRedis', { // 底层接口
method: 'POST',
body: JSON.stringify(data),
headers: new Headers({
'Content-Type': 'application/json',
"x-xsrf-token": e.data.abp
})
}).then(function (res) {
if (res.status == 200) {
timer = setTimeout(function () {
fetchKey();
},1000);
}
})
}
fetchKey();
}
}, false);
}
findForver();
worker线程向主线程发送信息
self.addEventListener('message', function (e) {
self.postMessage('You said: ' + e.data);
}, false);
// 上面代码中,self代表子线程自身,即子线程的全局对象。因此,等同于下面两种写法。
// 写法一
this.addEventListener('message', function (e) {
this.postMessage('You said: ' + e.data);
}, false);
// 写法二
addEventListener('message', function (e) {
postMessage('You said: ' + e.data);
}, false);
关闭worker线程
// 主线程
worker.terminate();
// Worker 线程
self.close();