JS setTimeout/setInterval最大延时值的问题解决方法

内容摘要
这篇文章主要为大家详细介绍了JS setTimeout/setInterval最大延时值的问题解决方法,具有一定的参考价值,可以用来参考一下。

对此感兴趣的朋友,看看idc笔记做的技术笔记。先来
文章正文

这篇文章主要为大家详细介绍了JS setTimeout/setInterval最大延时值的问题解决方法,具有一定的参考价值,可以用来参考一下。

对此感兴趣的朋友,看看idc笔记做的技术笔记。先来看这样一段代码:

/**
 * @param 
 * @arrange (www.idcnote.com)
 **/
function update() {
    loadData().then(function(data) {
        $('#content').html(data.content);
        var delay = data.nextUpdateTime - new Date();
        if (delay > 0) {
            setTimeout(update, delay);
        }
    });
}
其流程非常简单:通过AJAX加载数据后更新HTML的内容;如果有指定下次更新时间,则通过计时器在该时间点再执行一次整个流程。要说这段代码有什么隐患的话,那就是data.nextUpdateTime与当前时间的时间差(即delay变量的值)比较小的时候,会导致内容频繁更新。但这是属于正常的业务逻辑,要优化就只能牺牲内容更新的即时性。然而这里我要说的是,当时间差非常大的时候,也会出现同样的问题。下面模拟一下这个场景:

/**
 * @param 
 * @arrange (www.idcnote.com)
 **/
function log() {
    console.log('executed');
}

var nextUpdateTime = new Date();
// 设为一个月后
nextUpdateTime.setMonth(nextUpdateTime.getMonth() + 1);

var delay = nextUpdateTime - new Date();
setTimeout(log, delay);
这段代码的原意是让log函数在一个月后执行,但是运行一下就可以发现,该函数会马上执行。为什么会这样呢?搜一下相关内容可以发现,setTimeout是使用Int32来存储延时参数值的,也就是说最大的延时值是2^31-1。一旦超过了最大值,其效果就跟延时值为0的情况一样,也就是马上执行。这个最大的延时值已经接近一个月了,一般情况下,用户也不会长时间开着一个网页,如果真开了这么久,那就刷新一下吧:

/**
 * @param 
 * @arrange (www.idcnote.com)
 **/
function update() {
    loadData().then(function(data) {
        $('#content').html(data.content);
        var delay = data.nextUpdateTime - new Date();
        if (delay > 0) {
            // 限制最大延时值为一天
            var ONE_DAY = 24 * 60 * 60 * 1000;
            if (delay > ONE_DAY) {
                setTimeout(function() {
                    window.location.reload();
                }, ONE_DAY);
            } else {
                setTimeout(update, delay);
            }
        }
    });
}
同样的问题也存在于setInterval中。这也算是Javascript中一个比较隐蔽的坑了。

注:关于JS setTimeout/setInterval最大延时值的问题解决方法的内容就先介绍到这里,更多相关文章的可以留意

代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!