JS setInterval 定时器导致页面卡死

DeepLearning
• 阅读 13258
使用场景

N多年前,leader让做一个网页,给了一个设计png,content部分分好几块,然后这几块内容里面的数据不停的来回切换,当时第一反应就是setInterval 循环播放,一个网页大概半天时间就做好了,成品跟设计png几乎一模一样,很满意,打包发给了leader。
然而,过了几天,leader说你做的网页为什么过了会,点什么都没反应,你去看看怎么回事。当时就觉得奇怪,我本地运行的好好的,没有任何异常,也没他说的卡死啊,然后就网上各种搜索,看看问题到底出在哪里。后来只记得当时的产物是
`window.setInterval(() => {

setTimeout(fun, 0)

}, 30000)`

并不知道为什么要这样做,只知道这样写了以后,网页不会再卡死。当时也没有去研究到底为什么。依稀记得当时也网上搜索了,没有找到答案。

后续

后面工作很多年,只要使用到循环就一直按照这种写法,没有遇到过卡死的问题,有次听公开课的时候,问了下老师,为什么要这样写,老师只说这样写性能好,并没有说为什么。

今天刚好看同事代码,告诉她循环不建议那么写,我给你找个比较好的写法,我自己也说不上来为什么要这样写,既然疑惑这么多年,今天刚好有空,我来查查为什么。

网上的说明 setinterval不会清除定时器队列,每重复执行1次都会导致定时器叠加,最终卡死你的网页
其原因与JS引擎线程有关(又得研究下JS引擎线程了) 但是setTimeout是自带清除定时器的

参考 https://blog.csdn.net/helenwe...

另外搜索到一些弊端
弊端1:setInterval会无视错误代码,即使代码报错,还是会一直执行下去。

弊端2:setInterval会无视网络延迟,很多人会有需求需要1秒更新一次数据,然后就有可能会定时发送请求给服务器请求,假如服务器请求数据发生延迟等等情况的时候,setInterval不会等到请求数据完之后才去去执行下一次请求,他会在当你发生第一次请求的时候就已经开始计时,并且无论有没有请求完成,只有时间一到下一秒的时候,就会再次发送请求。很容造成请求堵塞,或者渲染堵塞,严重的会之间卡死。

注:vue 项目的时候,如果页面使用到循环定时器,调用后台接口出现异常,在切换路由地时候并不能清除定时器。(目前我测试出来,是这样的)
` beforeRouteLeave(to, from, next) {

console.log('beforeRouteLeave')
this.clearTimer()
next() //一定不要忘记写

}`

弊端3:很多时候越跑越快的问题。

解决方案:使用setTimeout和递归(自我调用)

例如:

使用 setInterval 方案(不推荐使用)

`setInterval(function(){

console.log('做点什么吧')

},1000)`
使用 setTimeout 方案 (推荐使用,完美代替setInterval) 注:有待验证

`var demo = function(){

console.log('做点什么吧')
setTimeout(demo, 1000)       

}`

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Souleigh ✨ Souleigh ✨
4年前
为什么要用 setTimeout 模拟 setInterval ?
在JS事件循环之宏任务和微任务中讲到过,setInterval是一个宏任务。用多了你就会发现它并不是准确无误,极端情况下还会出现一些令人费解的问题。下面我们一一罗列..推入任务队列后的时间不准确定时器代码:setInterval(fn(), N);上面这句代码的意思其实是fn()将会在N秒之后被推入任务队列。所以,在setInterval
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Karen110 Karen110
4年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Easter79 Easter79
4年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
4年前
PHP之定时任务(绝对实用)
在工作中经常会用到定时任务,除了在js中有定时器这个玩意可以用于前端页面的定时任务;那么后端PHP如何设置定时任务呢?一.如下是javascript中使用setTimeout和setInterval设置定时任务:1setTimeout(function(){2console.log('timeout');
Stella981 Stella981
4年前
Fiori 里周期性检查window size大小的变化
UI5框架里使用this.setInterval注册了一个每隔200毫秒(Core.\_I\_INTERNAL)执行的job:!(https://userimages.githubusercontent.com/5669954/33226812cc73c03cd1d011e79fe18ae24af15408.png)!(http
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
js基础之setTimeout与setInterval原理分析
setTimeout与setInterval概述setTimeout与setInterval是JavaScript引擎提供的两个定时器方法,分别用于函数的延时执行和循环调用。前者的主要思想是通过一个定时器,让函数在计时结束后再执行;后者则是每隔一定的时间,
DeepLearning
DeepLearning
Lv1
此曲只应天上有,人间能得几回闻。
文章
4
粉丝
0
获赞
0