V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
lisisi
V2EX  ›  JavaScript

setInterval 长时间循环之后,会导致浏览器标签页卡死,须要怎么避免呢?

  •  
  •   lisisi · 2021-03-13 16:04:24 +08:00 · 4179 次点击
    这是一个创建于 1333 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在页面上写了一个定时器,每秒运行一次,24 小时后销毁。结果发现超过 24 小时,这个页面大概率就卡死了,必须要重新打开浏览器才能使用。

    检查了几个方面: 1 、内存没有溢出。 2 、服务器正常,换个浏览器都能正常打开这个页面。 看起来,只是浏览器( Chrome 、新 Edge 都有这个情况)当前进程或线程卡死了,关闭再打开浏览器就可以正常访问。

    <p>显示运行次数:</p>
    <p id="demo"></p>	
    	
    <script type="text/javascript">
        var timesRun = 0;
        var myVar = setInterval(function(){
            timesRun += 1;
            if(timesRun === 86400){
                clearInterval(myVar);
            }
    	document.getElementById("demo").innerHTML=timesRun;    
        }, 1000);
    </script>	
    
    23 条回复    2022-03-22 21:25:44 +08:00
    learningman
        1
    learningman  
       2021-03-13 16:52:53 +08:00
    一个页面要开 24h 换 node.js 吧。。。。
    lisisi
        2
    lisisi  
    OP
       2021-03-13 17:08:55 +08:00
    @learningman 服务器没卡死(换个浏览器正常打开),是页面卡死,换 node.js 能解决吗?
    usw
        3
    usw  
       2021-03-13 17:09:03 +08:00   ❤️ 4
    setInterval 在标签页非激活状态下会暂停并且存在积压问题,需要长时间的稳定可以试一下 setTimeout 嵌套,或者 requestAnimationFrame 嵌套
    wxsm
        4
    wxsm  
       2021-03-13 17:16:36 +08:00   ❤️ 1
    #3 说得对。

    另:#1 这种估计只看了标题。
    des
        5
    des  
       2021-03-13 17:22:03 +08:00 via iPhone
    @wxsm
    #1 很实在的建议啊,也不是无关的回答
    再者说了,一个页面长时间不激活,也会被直接暂停,edge 就是这个逻辑
    lisisi
        6
    lisisi  
    OP
       2021-03-13 17:28:59 +08:00
    @des Edge 麻烦的地方在于,从被休眠的暂停状态中,恢复的时候,这个卡死的页面手动刷新也活不过来,必须关闭 Edge 再打开,感觉是 Edge 整个进程或线程卡死了
    otakustay
        7
    otakustay  
       2021-03-13 17:45:02 +08:00
    #3 已经说了,setInterval 积压导致恢复的时候有 N 多个 callback 连续执行所以卡住了,用 setTimeout 嵌套就行
    PeakFish
        8
    PeakFish  
       2021-03-13 18:50:20 +08:00 via iPhone
    换 settimeout
    wxsm
        9
    wxsm  
       2021-03-13 20:44:58 +08:00
    @des 请问页面开 24h 跟用不用 node.js 有啥关系
    lisisi
        10
    lisisi  
    OP
       2021-03-13 20:49:34 +08:00
    @usw
    @otakustay
    @PeakFish

    谢谢,换 setTimeout 试试
    love
        11
    love  
       2021-03-13 21:10:59 +08:00
    确定是 setInterval 会积压?感觉不合逻辑啊? setInterval 有保证调用次数的说明吗?哪怕暂停,哪怕间隔不准也要保证次数?

    按正常想法,在后台暂停时不会再记下错过的次数在重新得到焦点时一次性把错过的次数调用完(这个其实很好验证
    thulof
        12
    thulof  
       2021-03-13 23:39:55 +08:00
    setInterval 卡死这个问题有确定的触发条件吗?是否可以通过定期取消重新设置的方式来实现呢?
    babyfaction
        13
    babyfaction  
       2021-03-14 00:08:46 +08:00
    @love 会积压, 测试一下就知道了;
    autoxbc
        14
    autoxbc  
       2021-03-14 00:58:40 +08:00
    就像不应该用 eval 一样,应该完全弃用 setInterval
    ccraohng
        15
    ccraohng  
       2021-03-14 09:05:08 +08:00 via iPhone
    建议不要用 count 计数,实时获取当前时间,requestAnimationFrame setTimeout 都不能保证前后调用时间间隔
    whywhywhy
        16
    whywhywhy  
       2021-03-14 11:41:26 +08:00
    @autoxbc 请问这是什么原因要完全弃用呢
    zhuweiyou
        17
    zhuweiyou  
       2021-03-14 11:55:08 +08:00
    改成 setTimeout
    zhuweiyou
        18
    zhuweiyou  
       2021-03-14 11:55:44 +08:00
    另外不要用 count++, 改成进来获取一下时间, 然后每次 loop 获取一下时间 做减法
    peterjose
        19
    peterjose  
       2021-03-14 20:02:14 +08:00
    我记得页面切出去的时候 浏览器会自动把 setinterval 降低到 1s 执行一次 然后就堆积了
    ch2
        20
    ch2  
       2021-03-15 11:18:44 +08:00
    防抖动、rate-limit 了解一下
    Roger006
        21
    Roger006  
       2021-03-16 17:10:49 +08:00
    首先每秒都执行一次,使用 setTimeout 和 setInterval 用累加值都不准确 [代码写的时间间隔并不能直接等于实际代码执行间隔时间] ,建议保留原始时间,每次执行方法获取当前时间,然后做减法获取剩余时间。前边#15 #18 已经说明过了
    justsosososo
        22
    justsosososo  
       2021-03-18 11:19:09 +08:00
    个人见解,不对勿喷,我感觉问题应该出现在那个 function,因为函数声明每次都会在堆内存中开辟一块空间,你这样一直循环目测会一直增加, lz 可以试着 把函数定义在外面,然后试试,
    TKI
        23
    TKI  
       2022-03-22 21:25:44 +08:00
    #3 说的有点道理,楼主最后是通过 递归 setTimeout 解决的吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2696 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 15:26 · PVG 23:26 · LAX 07:26 · JFK 10:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.