一、问题来源。
在项目中,我们经常有这样的需求,一个页面初始化后,需要不断的去请求后端,来获取当前某个记录的最新状态。
显然,这个可以用setTimeout以及回调中继续setTimeout来实现。
我们假设定时器是在页面#/test/aaa上创建的。
但是,会遇到以下两个问题,我从#/test/aaa 这个页面切换到 #/test/bbb页面后如果停留在#/test/bbb,定时器还在跑。
其次,如果我不断在#/test/aaa 和 #/test/bbb两个页面之间不断的切换,而且切换时间小于定时器的间隔时间时,也会出现
重复创建setTimeout的情况。
现在的问题就是,我们如何做到管理定时器。
二、示例代码。
created() { if ( this.timeOut ) { clearTimeout(this.timeOut); } this.getListIng(); }, computed: { timeOut: { set (val) { this.$store.state.timeout.compileTimeout = val; }, get() { return this.$store.state.timeout.compileTimeout; } }, }, methods: { getListIng() { // 这里是一个http的异步请求 if ( getUrlModule() == 'aaa' ) { let _this = this; this.timeOut = setTimeout(() => { _this.getListIng(); }, 5000); } else { this.timeOut = ''; } }, }
(1)如上面代码所示,当创建页面(created执行)时,会先判断变量this.timeOut是否存在,如果存在,先clearTimeout掉。
(2)而,this.timeOut这个变量对应的是全局store里的this.$store.state.timeout.compileTimeout
。并且是双向绑定的,这个
请自行搜索vue2.0中computed用法。
(3)在我们的主函数getListIng()中,会先使用函数getUrlModule()根据url判断当前页面是否是aaa页面,如果是的,就执行setTimeOut,
如果不是,就不行执行了,并且设置this.timeOut = '';
我们假设上面没有if ( getUrlModule() == 'aaa' )
这句判断,会出现,当我们已经跳出了当前aaa页面,去了bbb页面并且一直停留在bbb页面时,
还有setTimeout在执行,就会不断有http的请求。
如果没有if ( this.timeOut ) { clearTimeout(this.timeOut); }
这句代码。当我们不断在2个页面之间切换时,且切换的频率很高。会出现多次创建
setTimeout的情况。这个逻辑稍微有点绕,请阅读者自行演算。
三、我们必须清楚的事实。
(1)vue中$store里创建的变量,其实是全局变量,这个变量在切换页面时不会清除,当我们刷新页面时会清除掉。
(2)在前端页面中,当我们刷新页面时,会将当前页面之前创建的setTimeout以及其他定时器都清除掉。但是,切换页面(仅仅是路由切换)
是不会清除的。
(3)setTimeout、setinterval有本质的不同,前者只执行一次,除非你在回调中,不断的调用,而后者是不间断调用的。但是,我在各种实践中发现,
还是setTimeout好用。因为,setTimeout可以根据条件,及时在回调中停用。如果采用setinterval,我们很有可能捕捉不到停用的条件而无法停用。
补充:Vue之SetTimeout
1.前言
相信很多人都遇到过这样的问题,页面数据需要不断的刷新,也就是不断的发送ajax请求来更新数据,那么在vue中怎样做才比较好呢?这里介绍一下我踩的坑,以及解决方案
2.问题
settimeout用来调用请求数据,但是我遇到的问题就是,没有用合适的方式去关闭settimeout,出现了离开当前页面,请求还在不断的发送问题,这样给服务器带来了无必要的压力。附上之前的代码:
self.deployTimeOutId = setTimeout(() => { self.getDeployList(false); }, 5000);
说明:这一段代码是嵌在getDeployList方法中的,离开当前页面的是时候,必须要去手动的把这个settimeout清除才行。一般这个写在destoryed()这个钩子里。
window.clearTimeout(this.deployTimeOutId);
虽然这样处理了,但在逻辑比较复杂的情况下,还是出现了没有关闭的情况,而且排查起来很痛苦。下面介绍一种针对Vue比较好的做法。
3.解决方案
let self=this; if (self && !self._isDestroyed) { setTimeout(() => { if (self && !self._isDestroyed) self.getDeployList(); }, 5000); }
_isDestroyed这个属性表示的是当前这个组件是否有被销毁,true表示当前的组件已经被销毁,通过上面这个判断,我们就不需要自己手动的去用ID来清除了,这个就相当于递归嘛,有了一个结束判断,避免了死循环咯~~
总结
以上所述是小编给大家介绍的vue项目开发中setTimeout等定时器的管理问题,希望对大家有所帮助,如果大家有任何疑问请
给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- [音展纪念碟]2006年《TAA台湾第十六届国际HI-ENDHI-FI音响展》2cd[WAV]
- 中国音乐地图之听见西藏山歌牧歌酒歌2020[WAV分轨]
- 王宏伟2017-永远的红飘带[太平洋影音][WAV+CUE]
- 费翔.1997-NOW现在【第一中国】【WAV+CUE】
- 新格合唱团.1981-我唱你和2辑(滚石新格民歌系列)【新格】【WAV+CUE】
- 陈柏宇.2011-QUINQUENNIUM【SONY】【WAV+CUE】
- 雨果唱片-《金唛系列-蔷薇依韵琼瑶》WAV
- 陈百强《凝望(2012华纳LPCD45限量版)[DMI]》[WAV整轨]
- 模拟之声慢刻CD《徐小凤45周年》[德国母带][低速原抓WAV+CUE]
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- 《王菲 单曲合集》[FlAC/分轨][520MB]
- 《费玉清 原味再现 水长流》[WAV+CUE][430MB]
- 群星.1992-畅销榜老歌金曲10CD【风格】【WAV+CUE】
- 孙悦.2024-时光音乐会【金蜂】【WAV+CUE】