Как изящно очистить таймер в Vue?

внешний интерфейс Vue.js

«Эта статья участвовала в приказе о созыве Haowen, нажмите, чтобы просмотретьДвойные заявки на внутреннюю и внешнюю стороны, призовой фонд в 20 000 юаней ждет вас, чтобы бросить вызов!"

предисловие

Очистите таймер, я считаю, что значительное количество людей написали это:

export default {
  data() {
    return {
      timer: null
    }
  },
  
  mounted() {
    this.timer = setInterval(() => {
      console.log('setInterval')
    }, 2000)
  },
  
  beforeDestroy() {
    clearInterval(this.timer)
  }
}

Это обычный кусок кода, по крайней мере несколько мелких партнеров вокруг меня (все с 1-3 годами опыта) написали его так, здесь есть 3 неэлегантные проблемы:

  • Таймер имеет значение null после того, как clearInterval не очищен.
  • Распределение кода для запуска и сброса таймера в двух местах ухудшает читабельность и удобство сопровождения и, по словам Юты, затрудняет программную очистку того, что мы создали.
  • Таймер определяется в данных.На самом деле, таймер не нуждается в какой-либо отзывчивой операции.Необходимо определять его в данных, но это приведет к потере производительности.

оптимизация

Перейдите непосредственно к коду:

export default {
  data() {
    return {
    }
  },
  
  mounted() {
    let timer = setInterval(() => {
      console.log('setInterval')
    }, 2000)
    this.$once('hook:beforeDestroy', () => {
      clearInterval(timer)
      timer = null
    })
  }
}

Здесь хук используется для мониторинга жизненного цикла beforeDestroy, поэтому нужно только определить таймер в жизненном цикле, и все вышеперечисленные проблемы будут решены.

Производный вопрос: beforeDestroy не срабатывает?

В фоновой системе мы часто устанавливаем кеш страниц, и когда маршрут кэшируется keep-alive, жизненный цикл beforeDestroy не соблюдается, поэтому некоторые друзья думают, что очистка таймера в beforeDestroy выполнена, и они даже не проверьте это Верхний таймер не сброшен. Зная причину, легко решить с помощью активации и деактивации этих двух необработанных хуков:

export default {
  data() {
    return {
    }
  },
  
  mounted() {
    let timer = setInterval(() => {
      console.log('setInterval')
    }, 2000)
    this.$on('hook:activated', () => {
      if (timer === null) { // 避免重复开启定时器
        timer = setInterval(() => {
          console.log('setInterval')
        }, 2000)
      }
    })
    this.$on('hook:deactivated', () => {
      clearInterval(timer)
      timer = null
    })
  }
}

Здесь следует отметить, что из-за кеширования вам нужно использовать $on вместо $once, иначе он не будет запущен снова после одного выполнения.

благодарный

Спасибо за прочтение, если эта статья была вам полезна, не забудьте поставить лайк и поддержать ❤️.

Если в этой статье есть какие-либо ошибки или недостатки, пожалуйста, исправьте меня в комментариях.