Реализация коррекции обратного отсчета во внешнем интерфейсе JavaScript

внешний интерфейс JavaScript
Реализация коррекции обратного отсчета во внешнем интерфейсе JavaScript

Обратный отсчет веб-страницы переднего плана — очень распространенное приложение, и мы всегда можем увидеть его в пиках активности на крупных торговых сайтах. Но на практике мы часто обнаруживаем, что когда веб-страница не обновляется, а программа обратного отсчета продолжает работать, отображаемое время будет все медленнее и медленнее, чем фактическое время.Я считаю, что у каждого есть опыт обновления страницы, когда время seckill приходит. Причину понять несложно: в обратном отсчете обычно используется таймер (setTimeoutилиsetInterval) реализации, а однопоточная функция JavaScript приводит к тому, что асинхронные задачи в очереди задач не могут выполняться вовремя, когда стек выполнения основного потока заблокирован, поэтому браузер не может гарантировать, что код всегда будет выполняться вовремя после времени установленный таймером expires , что создает смещение обратного отсчета.

Общее решение состоит в том, что интерфейс регулярно отправляет запрос на сервер для получения последней разницы во времени для калибровки времени обратного отсчета, который представляет собой разницу между активным (задайте временной запрос в программе) или пассивным (нажата F5). пользователем). Этот метод прост, но также немного груб.Следующее предоставляет метод, который может исправить обратный отсчет, не полагаясь в определенной степени на сервер. Код не оригинальный, а исходники давно забыты, записывайте процесс обучения здесь, чтобы не забыть. Если есть какие-либо нарушения, пожалуйста, свяжитесь со мной.

В первую очередь нам нужно смоделировать среду, в которой основной поток заблокирован, и в то же время основной поток не может быть заблокирован все время:

setInterval(function(){ 
  let j = 0
  while(j++ < 100000000)
}, 0)

Затем основной код:

const interval = 1000
let ms = 50000,  // 从服务器和活动开始时间计算出的时间差,这里测试用 50000 ms
let count = 0
const startTime = new Date().getTime()
let timeCounter
if( ms >= 0) {
  timeCounter = setTimeout(countDownStart, interval)
}
 
function countDownStart () {
   count++
   const offset = new Date().getTime() - (startTime + count * interval) // A
   let nextTime = interval - offset
   if (nextTime < 0) { 
       nextTime = 0 
   }
   ms -= interval
   console.log(`误差:${offset} ms,下一次执行:${nextTime} ms 后,离活动开始还有:${ms} ms`)
   if (ms < 0) {
     clearTimeout(timeCounter)
   } else {
     timeCounter = setTimeout(countDownStart, nextTime)
   }
 }

Обоснование кода несложно: рекурсивно вызываяsetTimeoutВыполните операцию обратного отсчета. Каждый раз, когда функция выполняется, переменная count будет поддерживаться для записи количества выполненных обратных отсчетов.Используя формулу в коде A, можно рассчитать отклонение между текущим временем обратного отсчета выполнения и фактическим временем выполнения, а затем в следующий раз можно рассчитать время для выполнения обратного отсчета.

Эта статья была впервые опубликована в моем блоге (Нажмите здесь, чтобы просмотреть), добро пожаловать, чтобы следовать.