美文网首页让前端飞Web前端之路
页面切换 定时器延迟 setInterval

页面切换 定时器延迟 setInterval

作者: Tiny_z | 来源:发表于2018-05-21 13:56 被阅读202次

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

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

大概6秒执行了14次


当前页

大概11秒执行14次


切换标签页

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

// time worker

var 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就可以了

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

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

演示地址
完整代码

相关文章

  • 页面切换 定时器延迟 setInterval

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

  • 第十三节 JavaScript 定时器 单线程

    一、定时器 1. JS存在两种定时器 setTimeout() 延迟定时器 setInterval() ...

  • 第十三节: JavaScript 定时器

    1. JS存在两种定时器 setTimeout() 延迟定时器setInterval() 循环...

  • vue中使用计时器setInterval的坑

    vue中的setInterval在页面离开之后仍会执行,在切换多个路由之后,定时器的速度会越来越快。加入下面代码,...

  • js轮播的bug

    切换标签页setInterval不工作BUG 浏览器有一个BUG,当页面标签切换时,setInterval回不工作...

  • JQuery学习

    今日任务 使用JQuery完成页面定时弹出广告 定时器: ​ setInterval clearInt...

  • jQuery学习笔记

    任务 使用JQuery完成页面定时弹出广告 技术要求 定时器:setInterval clearInter...

  • js中的定时机制与函数节流

    js中常用setTimeout()和setInterval()创建定时器,实现延迟或定时执行。 定时机制 js是运...

  • JS定时器

    定时器 setInterval 与 setTimeout的区别 setInterval setInterval(...

  • js date

    创建 Date 对象的语法: 定时器 setInterval 循环定时器 语法: setInterval(fun...

网友评论

    本文标题:页面切换 定时器延迟 setInterval

    本文链接:https://www.haomeiwen.com/subject/uxrfjftx.html