Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 定期刷新的Vue屏幕,安全完成_Javascript_Vue.js_Timer - Fatal编程技术网

Javascript 定期刷新的Vue屏幕,安全完成

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中的另一个代码抛出一个错误,在这种情况下刷新停止,或

我在Vue/Nuxt中有一个页面,需要每隔几秒钟刷新一次项目列表。这是一个SPA,它对服务器执行Axios抓取以获取更新信息。目前,我有这样的想法:

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"
});