Javascript 定期刷新的Vue屏幕,安全完成
我在Vue/Nuxt中有一个页面,需要每隔几秒钟刷新一次项目列表。这是一个SPA,它对服务器执行Axios抓取以获取更新信息。目前,我有这样的想法:Javascript 定期刷新的Vue屏幕,安全完成,javascript,vue.js,timer,Javascript,Vue.js,Timer,我在Vue/Nuxt中有一个页面,需要每隔几秒钟刷新一次项目列表。这是一个SPA,它对服务器执行Axios抓取以获取更新信息。目前,我有这样的想法: methods: { doRefresh() { setTimeout(function() { // trigger server fetch here doRefresh(); }, 5000); } } 它可以工作,除非doRefresh中的另一个代码抛出一个错误,在这种情况下刷新停止,或
methods: {
doRefresh() {
setTimeout(function() {
// trigger server fetch here
doRefresh();
}, 5000);
}
}
它可以工作,除非doRefresh中的另一个代码抛出一个错误,在这种情况下刷新停止,或者不知何故代码被调用了两次,而我同时得到了两个计时器
另一种方法是只调用setInterval()一次。问题是,即使在我离开页面后,它仍会继续运行。我可以存储setInterval()返回的引用,然后在销毁的()钩子中停止它。但同样,一个错误可能会阻止这种情况发生
是否有一种安全可靠的方法可以在Vue页面上运行计时器,并在用户离开页面时将其销毁?这种方法加上try-catch是一种方法,请查看以下代码片段:
Vue.component(“间隔组件”{
模板:`
{{lastRefreshed}}
开始`,
数据(){
返回{
timeoutId:未定义,
最后刷新:未定义
};
},
方法:{
doJob(){
如果(Math.random()>0.9)抛出新错误();
this.lastRefreshed=新日期();
控制台日志(“工作完成”);
},
init(){
如果(this.timeoutId)返回;
这个。run();
},
运行(){
console.log(“循环已启动”);
const vm=这个;
this.timeoutId=setTimeout(函数(){
试一试{
vm.doJob();
}捕获(e){
控制台日志(e);
}最后{
vm.run();
}
}, 2000);
}
},
销毁(){
clearTimeout(this.timeoutId);
控制台日志(“已销毁”);
}
});
组件(“包装器”{
模板:`创建
毁灭
`,
数据(){
返回{
毁灭:真的
};
},
方法:{
销毁{
这是真的;
},
创建(){
这个是假的;
}
}
});
新Vue({
el:“应用程序”
});
<div id="app">
<wrapper/>
</div>
Vue.component("interval-component", {
template: `
<div> {{lastRefreshed}}
<button @click="init">Start</button></div>`,
data() {
return {
timeoutId: undefined,
lastRefreshed: undefined
};
},
methods: {
doJob() {
if (Math.random() > 0.9) throw new Error();
this.lastRefreshed = new Date();
console.log("Job done");
},
init() {
if (this.timeoutId) return;
this.run();
},
run() {
console.log("cycle started");
const vm = this;
this.timeoutId = setTimeout(function() {
try {
vm.doJob();
} catch (e) {
console.log(e);
} finally {
vm.run();
}
}, 2000);
}
},
destroyed() {
clearTimeout(this.timeoutId);
console.log("Destroyed");
}
});
Vue.component("wrapper", {
template: `<div> <button @click="create" v-if="destroyed"> Create</button>
<button v-else @click="destroy">Destroy</button>
<interval-component v-if="!destroyed" /></div>`,
data() {
return {
destroyed: true
};
},
methods: {
destroy() {
this.destroyed = true;
},
create() {
this.destroyed = false;
}
}
});
new Vue({
el: "#app"
});