@kirillleogky

Как остановить местное время и запустить время по координатам?

У меня есть setInterval по текущему местоположению:
const timerId = window.setInterval(setCurrTime, 100);

setCurrTime
export default async function setTime(date = new Date()) {
  const time = document.querySelector('#time');
  const currDate = await date;

  let hours = currDate.getHours();
  let minutes = currDate.getMinutes();

  if (hours <= 9) hours = `0${hours}`;
  if (minutes <= 9) minutes = `0${minutes}`;

  time.innerText = '';
  time.innerText = `${hours}:${minutes}`;
}



Далее в коде я сбрасываю timerId:
clearInterval(timerId);


И далее я хочу запустить время, но с привязкой к определённому местоположению
Это у меня достигается данной функцией которую я передаю аргументом в функцию setCurrTime
setSearchTime(useGeocod(areaSearch))

Что конкретнее я хочу сделать:
  • При загрузке страницы
    const timerId = window.setInterval(setCurrTime, 100);

  • Потом при определённых условиях сбросить setInterval и установить новый
    clearInterval(timerId);
    window.setInterval(setCurrTime, 100, setSearchTime(useGeocod(areaSearch)));


setSearchTime(useGeocod(areaSearch)) - асинхронная функция, но возвращает всегда нужное время, но когда закидываю в новый setInterval, то устанавливается только одно время без обновления.

Как мне остановить один setInterval и запустить почти тот же, но с аргументом, и чтобы он обновлялся как первый?
Это важно, чтобы обновлялось, так как это функционал часов.
  • Вопрос задан
  • 102 просмотра
Решения вопроса 1
@Flying
Ошибка довольно очевидна, хотя и размазана по коду. Однако причина её появления - в том что вы плохо понимаете те механизмы которые пытаетесь использовать. Другими словами это ошибка не техническая, а ошибка от недостатка знаний.

Ваш текущий код работает по причине того что вы используете неявное создание нового объекта на каждый вызов через указание new Date() в качестве значения по-умолчанию. Это значение по-умолчанию вас и сбивает с толку т.к. оно выглядит как своеобразный генератор значений, хотя по факту им не является.

Кроме того await date тоже по факту работает не совсем так как вы (скорее всего) ожидаете. Из MDN: "If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise." Таким образом const currDate = await date в вашем случае эквивалентно const currDate = date.

Далее, следите за руками:

Сначала вы передаёте в setInterval функцию без дополнительных аргументов. Она работает по причинам, описанным выше.

Затем вы передаёте в setInterval() значение вызова setSearchTime() третьим аргументом (т.е. аргументом для интервальной функции). При этом, как вы сами пишете - функция setSearchTime() у вас возвращает Promise что по определению - обещание вернуть одно значение.

Таким образом когда вы передаёте этот третий аргумент - ваша функция начинает получает значение аргумента date (т.е. перестаёт отрабатывать генерация значения по-умолчанию). При первом вызове ваш Promise, переданный в качестве аргумента в интервальную функцию, переходит в состояние fulfilled и отдаёт значение, но дальше этого уже не будет происходить т.к. Promise уже в состоянии fulfilled, так что вы будете всегда получать одно и то же значение. Однако это будет происходить не потому что setInterval не работает, а потому что вы и передаёте одно значение.

Если вы (сами или из описания выше) понимаете как всё это работает на самом деле - то решение проблемы становится очевидным: вам всего лишь нужно передавать в вашу функцию setCurrTime не значение времени, а функцию-генератор времени. Тогда её вызов на каждой итерации будет приводить к созданию нового значения времени и всё начнёт работать.

Также пара замечаний которые не относятся непосредственно к вашему вопросу, но являются важными:
  1. Ваша функция отображает время с точностью до минуты, но вызывается каждые 100 миллисекунд. Таким образом она 600 раз генерирует одно и то же значение что, очевидно, неразумно
  2. Сама функция преобразования времени у вас не показана, но важно чтобы эта функция не опиралась на setInterval в качестве источника информации о количестве прошедшего времени. Вместо этого вы должны всегда отталкиваться от new Date() и модифицировать этот объект. В качестве примера почему так попробуйте себе представить что компьютер с браузером в котором запущен ваш скрипт, был отправлен в гибернацию на какое-то время, а потом вернулся назад
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы