vue setInterval 생 성 및 인 스 턴 스 소각 실현

문제.
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>
이 코드 는 문제 가 없어 보이 지만 테스트 를 할 때 경로 가 이미 바 뀌 었 고 프로 세 스 로 그 를 가 져 오 는 인터페이스 가 계속 호출 되 고 있 습 니 다.심지어 인터페이스 호출 속도 가 매우 빠 르 고 1 초 에 여러 가지 요청 이 있 을 수도 있 습 니 다.
분석 하 다.
beforeDestory 는 구성 요소 가 소각 되 기 전의 생명주기 의 갈고리 입 니 다.이 갈고리 함 수 는 반드시 호출 될 것 입 니 다.그러나 setTimeout 을 철저히 소각 할 수 있 습 니까?답 은 안 돼.
콘 솔 을 열 면 인쇄 된 id 가 보 입 니 다.

클 리 어 타임 아웃 을 사용 할 때마다 지난번 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)
})
그 중 하 나 를 빠 뜨 렸 다 면 비슷 한 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 을 제외 하고 보통 제3자 라 이브 러 리 의 대상 예제 도 있다.예 를 들 어 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()
  })
}
이상 의 vue 가 setInterval 을 실현 하고 인 스 턴 스 를 없 애 는 것 은 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.여러분 께 참고 가 되 고 저 희 를 많이 사랑 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기