「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」 |
---|
定时轮询,我们第一个会想到的就是用setInterval
去实现
let milliseconds = 5000
window.timer = setInterval(()=>{
fun()
},milliseconds)
setInterval和setTimeout的区别
setInterval(function(){}, milliseconds)
:会不停的调用函数,不会清除定时器队列setTimeout(function(){}, milliseconds)
只执行函数一次
,自带清除定时器的
setInterval会符合我们的业务需求,然而也需要注意一些坑,单纯的使用setInterval会导致页面卡死!其原因与JS引擎线程有关,用通俗话说就是setInterval不会清除定时器队列,每重复执行1次都会导致定时器叠加,最终卡死你的网页。但是setTimeout是自带清除定时器的
,因此可以叠加使用:
window.setInterval(() => {
setTimeout(fun, 0)
}, 30000)
setTimeout能阻止某些重复性操作
// setTimeout能阻止某些重复性操作
// 如果我们能捕获到异常,可以限定异常大于10次时,我们将不再拉取数据,并且在异常 》1 且 《10 时,我们可以适当将间隔拉大,让服务器有休息的时间。
var failed = 0;
(function loopsiloop( interval ){
interval = interval || 5000; // default polling to 1 second
setTimeout(function(){
$.ajax({
url: 'foo.htm',
success: function( response ){
// do something with the response
loopsiloop(); // recurse
},
error: function(){
// only recurse while there's less than 10 failed requests.
// otherwise the server might be down or is experiencing issues.
if( ++failed < 10 ){
// give the server some breathing room by
// increasing the interval
interval = interval + 1000;
loopsiloop( interval );
}
}
});
}, interval);
})();
结束轮询
在需要结束轮询,或者beforeDestroy生命周期函数中销毁定时器
clearInterval(timer)
如果需要通过按钮手动结束轮询,在按钮的click事件响应函数中加上clearInterval(timer)
即可
vue项目实例
<p v-if="taskStatus==='数据拉取中'">数据拉取中</p>
data () {
return {
taskStatus: '',
dataTimer: null,
}
},
created () {
// 是否开启定时器
if (this.taskStatus === '数据拉取中') {
this.dataTimer = setInterval(() => {
setTimeout(()=>{
// 返回一个状态,如果不是数据拉取中则停止定时器,停止拉取数据
this.judgeStatus()
// 返回的数据渲染到页面
this.showData()
}, 0)
}, 5000)
}
},
destroyed () {
clearInterval(this.dataTimer)
},
methods: {
judgeStatus () {
axios.get('/judgeStatus').then((res) => {
if (res.status === 200) {
this.taskStatus = res.data.taskStatus
if (res.data.taskStatus !== '数据拉取中') {
clearInterval(this.dataTimer)
this.showData()
}
}
}).catch((error) => {
console.log(error);
})
}
}