浏览器页面进入后台后setTimeout不正确执行的解决方法

0.前言

        出于节能的考虑,一些浏览器(比如Chrome浏览器)会在页面进入后台等不活跃的状态时,延缓甚至暂停setTimeout等定时器的执行。在这个节能策略影响到前端页面的功能时,就需要想办法绕过此限制。

1.解决方法和原理

        本人翻阅了很多网络文章,发现使用web worker是一种比较合适的解决方案。经研究理解web worker的使用方法、结合前人经验、搭配自己的调试和优化,本人编写了一段仅实现上述功能,且简洁易于理解的代码,在此将制作好的轮子分享出来,作为个人的学习记录,也希望能帮助到后来者,同时也欢迎大家友好交流。

        本文不具体介绍web worker的使用方法,如需详细了解,请移步本文结尾的第3个参考文章链接。

let funtemp = function(time) {
    setTimeout(function() {
        self.postMessage(0);
    }, time);
}
let worker = new Worker(window.URL.createObjectURL(new Blob(['(' + funtemp.toString() + ')(' + time + ')'])));
worker.onmessage = function() {
    worker.terminate();
    //要延迟执行的内容
}

        其中funtemp函数创建了一个计时器,在time时间之后执行self.postMessage()方法,并传递一个(无意义的,此处为0)参数。createObjectURL()将上述函数封装成了一个临时url,因为worker必须由url创建。随后,创建worker并监听worker的消息。在time时间过后,worker返回消息,此时使用terminate()销毁worker释放资源,同时可以开始执行本来打算要延迟执行的代码段。

2.一个实际的例子

        结合一个本人实际使用的例子:JavaScript没有sleep函数,在我们需要sleep函数功能的时候,可以通过以下代码来实现,

function sleep(time) {
    return new Promise((resolve) => setTimeout(resolve, time));
}

        但这样的sleep函数会被本文旨在解决的问题困扰,所以在浏览器前端使用时,将其改成下面的代码,即可完美实现功能。

function sleep(time) {
    return new Promise((resolve) => {
        let funtemp = function(time) {
            setTimeout(function() {
                self.postMessage(0);
            }, time);
        }
        let worker = new Worker(window.URL.createObjectURL(new Blob(['(' + funtemp.toString() + ')(' + time + ')'])));
        worker.onmessage = function() {
            worker.terminate();
            resolve();
        }
    });
}

3.参考内容

浏览器页面处于不活跃状态时setInterval不定时执行 - 简书

前端如何使用web worker发布setInterval任务 - 简书

Web Worker 使用教程 - 阮一峰的网络日志

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值