为了账号安全,请及时绑定邮箱和手机立即绑定

页面切换 定时器延迟 setInterval

标签:
Html/CSS

最近做了一个小定时器的功能,但是在标签页切换后,定时器就会出现延迟。后面发现是在页面切换后,浏览器会自动延迟我们的定时器,以便于节约资源。

例子:开启一个定时器:0.5秒数字自增

大概6秒执行了14次


https://img1.sycdn.imooc.com//5d3084e500019b2a00050017.jpg

当前页

大概11秒执行14次


https://img1.sycdn.imooc.com//5d3084ec0001db0900050004.jpg

切换标签页

在我们切换标签页后,我们的定时器根据浏览器不同,已经能明显感觉到延迟了,这个时候如果我们要保持定时器精度,可以用web work来跑我们的代码,通过在worker里面开启定时器,发送message给外部,外部收到message,然后再执行操作,这样我们切换页面,但是worker不受影响,定时器就可以解决延迟了

// time workervar intervalIds = {};// 监听message 开始执行定时器或者销毁self.onmessage = function(e){    switch(e.data.command){        case 'interval:start': // 开启定时器
            var intervalId = setInterval(function(){
                postMessage({                    message: 'interval:tick',                    id: e.data.id
                })
            },e.data.interval);

            postMessage({                message: 'interval:started',                id: e.data.id
            });

            intervalIds[e.data.id] = intervalId;            break;        case 'interval:clear': // 销毁
            clearInterval(intervalIds[e.data.id]);

            postMessage({                message: 'interval:cleared',                id: e.data.id
            })            delete intervalIds[e.data.id];            break;
    }
}

开启worker

var worker = new Worker('./time-worker.js');var workerTimer = {    id: 0,    callbacks: {},    setInterval: function(cb, interval, context) {        this.id++;        var id = this.id;        this.callbacks[id] = { fn: cb, context: context };
        worker.postMessage({ command: 'interval:start', interval: interval, id: id });        return id;
    },    // 监听worker 里面的定时器发送的message 然后执行回调函数
    onMessage: function(e) {        switch (e.data.message) {            case 'interval:tick':                var callback = this.callbacks[e.data.id];                if (callback && callback.fn) callback.fn.apply(callback.context);                break;            case 'interval:cleared':                delete this.callbacks[e.data.id];                break;
        }
    },    // 往worker里面发送销毁指令
    clearInterval: function(id) {
        worker.postMessage({ command: 'interval:clear', id: id });
    }
};

worker.onmessage = workerTimer.onMessage.bind(workerTimer);

然后我们使用的时候,直接用worker.setInterval或者workerTimer.clearInterval就可以了

https://img1.sycdn.imooc.com//5d3084f50001076d00120017.jpg

使用web worker 延迟问题就解决了

如果需要加入setTimeout,也是一样的步骤



作者:Tiny_z
链接:https://www.jianshu.com/p/3571ca7e0573


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消