推荐关注
› Meteor
› JSLint - a JavaScript code quality tool
› jsFiddle
› D3.js
› WebStorm
推荐书目
› JavaScript 权威指南第 5 版
› Closure: The Definitive Guide
lisisi

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

  •  
  •   lisisi · Mar 13, 2021 · 6178 views
    This topic created in 2072 days ago, the information mentioned may be changed or developed.

    在页面上写了一个定时器,每秒运行一次,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 replies  •  2022-03-22 21:25:44 +08:00
    learningman
    learningman
    Mar 13, 2021
    1
    一个页面要开 24h 换 node.js 吧。。。。
    lisisi
    lisisi
    OP
    Mar 13, 2021
    2
    @learningman 服务器没卡死(换个浏览器正常打开),是页面卡死,换 node.js 能解决吗?
    usw
    usw
    Mar 13, 2021❤️4
    3
    setInterval 在标签页非激活状态下会暂停并且存在积压问题,需要长时间的稳定可以试一下 setTimeout 嵌套,或者 requestAnimationFrame 嵌套
    wxsm
    wxsm
    Mar 13, 2021❤️1
    4
    #3 说得对。

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

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

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