使用worker解决非激活页面(页面隐藏)代码不执行的问题。
场景描述:
学生端有个举手定时器,10ms执行一次倒计时动画,10s后通知服务器端,取消举手。
倒计时开始后,如果把学生页签切换,或者把浏览器最小化。此时倒计时会暂停,直到重新激活学生页面。
let num=1000; function settime(){ console.log(new Date().getMinutes()+":"+new Date().getSeconds()+" "+num); if(num > 0) { num--; setTimeout(()=>settime(),16); }else { num=0; } } settime();
下面是运行结果,标红为隐藏期间。
解决方法:
使用worker开启一个多线程。
var worker = new Worker("./js/demo1.js");
demo1.js执行上面的代码。
不受页面切换,或最小化的影响。
引申:什么是worker:
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。
Web Worker 有以下几个使用注意点。
(1)同源限制
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
(2)DOM 限制
Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document
、window
、parent
这些对象。但是,Worker 线程可以navigator
对象和location
对象。
(3)通信联系
Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
(4)脚本限制
Worker 线程不能执行alert()
方法和confirm()
方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
(5)文件限制
Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://
),它所加载的脚本,必须来自网络。
worker详细描述可参考阮一峰的文章