vue 实现setInterval 创建和销毁实例
作者:暴暴君 发布时间:2024-05-09 15:26:14
问题
setInterval 是间隔调用,与之类似的还有 setTimeout。这两个 API 通常用来做 ajax 短连接轮询数据。
比如有一个 logs.vue 是用来展示某个正在执行的进程产生的日志:
<template>
<div>
<p v-for="item in logList" :key="item.time">
<span>{{"[" + item.time + "]"}}</span>
<span>{{ item.log }}</span>
</p>
</div>
</template>
<script>
import { Component, Vue, Watch, Prop, Emit } from 'vue-property-decorator'
import { getLogList } from './api'
@Component({})
export default class extends Vue {
logList = []
timer = null
mounted(){
this.getData()
}
async getData(){
let r = await getLogList()
if(r && r.logList){
this.logList = r.logList
}
this.timer = setTimeout(()=>{
console.log(this.timer);
this.getData()
}, 1000)
}
beforeDestory(){
clearTimeout(this.timer)
this.timer = null;
}
}
</script>
这段代码看上去没啥问题,但是测试的时候你会发现,有时候路由已经跳转了,获取进程日志的接口依然在不断调用,甚至,有时候接口调用速度非常快,一秒可能有好几个请求。
分析
beforeDestory 是组件销毁前的生命周期的钩子,这个钩子函数一定会调用,但是能不能彻底销毁 setTimeout 呢?答案是不能。
打开控制台就能看到不断打印出来的 id
这是因为,每次使用 clearTimeout 清除掉的是上一次的 id, 而不是本次正要执行的,这种情况,对于使用 setInterval 也是一样的。
根本原因在于,每次调用 getData, this.timer 是在不断的被赋予新的值,而不是一成不变的。
在以前的原生 js 中,我们通常这样写:
var timer = null
function init(){
timer = setInterval(function(){
getData()
})
}
function getData(){}
window.onload = init
window.onunload = function(){
clearInterval(timer)
}
由于上面的 timer 始终保持一个值,所以这里的清除是有效的
解决
vue 提供了 程序化的事件 * 来处理这类边界情况
按照文档的说法,我们的代码可以这样来更改
<script>
import { Component, Vue, Watch, Prop, Emit } from 'vue-property-decorator'
import { getLogList } from './api'
@Component({})
export default class extends Vue {
logList = []
// timer = null
mounted(){
this.getData()
}
async getData(){
let r = await getLogList()
if(r && r.logList){
this.logList = r.logList
}
const timer = setTimeout(()=>{
this.getData()
}, 1000)
this.$once('hook:beforeDestroy', function () {
clearTimeout(timer)
})
}
}
</script>
这样写,还解决了两个潜在问题
在组件实例中保存这个 timer,最好只有生命周期钩子有访问它的权限。但是实例中的 timer 会视为杂物
如果建立代码独立于清理代码,会使得我们比较难于程序化地清理所建立的东西
如果你是在项目中引入了 ts,那么可能会导致在组件销毁的时候,定时器不能成功清除,这时候,你需要使用
const timer = window.setTimeout(()=>{
this.getData()
}, 1000)
this.$once('hook:beforeDestroy', function () {
window.clearTimeout(timer)
})
如果你漏掉了其中一个 window,那么很可能会遇上类似的 ts 报错:Type 'Timer' is not assignable to type 'number',这是因为 node typings
It seems like you are using node typings which override setInterval() as something that returns NodeJS.Timer. If you're running in the browser, it doesn't make a whole lot of sense to use these,
结论
我们可以通过 程序化的事件 * 来监听销毁我们创建的任何代码示例
除了 setTimeout 和 setInterval ,通常还有一些第三方库的对象示例,如 timePicker,datePicker,echarts图表等。
mounted: function () {
// Pikaday 是一个第三方日期选择器的库
var picker = new Pikaday({
field: this.$refs.input,
format: 'YYYY-MM-DD'
})
// 在组件被销毁之前,也销毁这个日期选择器。
this.$once('hook:beforeDestroy', function () {
picker.destroy()
})
}
来源:https://blog.csdn.net/zhai_865327/article/details/106457196


猜你喜欢
- 常见的双倍边距类问题都遇到过,但很少遇到这种有意思的,所以记录一下。这个BUG是发生在Standards模式下(就是包含XHTML或者HTM
- 本人最近在做字符识别,所以自行在网上寻找方法,接触到tesseract,自己按照网上方法做的时候,也遇到一些问题
- 这里记录的主要是一张图,设计者是Adit Gupta。图中显示编程领域的先驱,以及各种编程语言的历史。很具有吸引力。
- 写作背景最近本菜鸡有几个网站想要爬,每个爬虫的代码不一样,但 有某种联系,可以抽出一部分通用的代码制成模板,减少代码工作量,于是就有了这篇文
- 随着 Node.js v8 的发布,Node.js 已原生支持 async/await 函数,Web 框架 Koa 也随之发布了 Koa 2
- 1 存储过程1.1 什么是存储过程存储过程是一组为了完成某项特定功能的sql语句集,其实质上就是一段存储在数据库中的代码,他可以由声明式的s
- 详见代码如下: import threading import time import os import subprocess def g
- 有时需要获取远程网站的某些信息,而服务器又限制了GET方式,只能通过POST数据提交,这个时候我们可以通过asp来实现模拟提交post数据,
- 偶然在网上发现itchat这个框架,itchat是一个开源的微信个人号接口,它使python调用微信变得非常简单。看到网上有人发自己微信好友
- 它在Lynx里也会运行得很好:<%@ Language=VBScript %><HTML><
- 前言首先,一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系?ECMAScript是一个国际通过的标准化脚本语
- JSON编码支持的基本数据类型为 None , bool , int , float 和 str , 以及包含这些类型数据的lists,tu
- 为什么要用flash呢?动画流畅,视觉效果好缓存能力强那使用flash有什么问题呢?需要Flash播放器在M$的补丁打遍天下之前IE有那神奇
- 前言MySQL是目前非常流行的数据库之一,也是中小企业持久化存储的首选数据库。不同于我们日常学习,在实际应用中,MySQL服务都会挂载在某台
- F()函数F()函数的导入from django.db.models import F为什么要使用F()函数?一个 F()对象代表了一个mo
- 前言在搜集了很多文本语料之后,会开始漫长的数据清洗过程,通常要不断迭代。1. 问题描述有些文本数据中,会包含一些特殊符号。猜想可能是从某些富
- 数学模块import mathceil -- 上取整对一个数向上取整(进一法),取相邻最近的两个整数的最大值。import mathres
- 优化前后新老代码如下:from git_tools.git_tool import get_collect_projects, QQNews
- 诊断SQLSERVER问题常用的日志这里主要有两个:(1)Windows事件日志(2)SQLSERVER ErrorLog1、Windows
- Web抓取Web站点使用HTML描述,这意味着每个web页面是一个结构化的文档。有时从中 获取数据同时保持它的结构是有用的。web站点不总是