Skip to content

interval

Событие-тик, которым управляют ваши собственные события старта и остановки, плюс флаг «идёт» для интерфейса.

ts
const { tick, active } = interval({ ms, start, stop, leading });
// tick: Event<void>   active: Store<boolean>

Игровой или сессионный таймер

ts
import { interval } from "@virentia/core/utils";

const enteredGame = event<void>();
const leftGame = event<void>();

const { tick, active } = interval({ ms: 1000, start: enteredGame, stop: leftGame });

reaction({ on: tick, run: () => { elapsed.value += 1; } });

active — обычное читаемое состояние, а не служебная деталь: индикатор паузы или мигающую точку можно привязать прямо к нему.

Поллинг, пока открыт экран

Привязываем время жизни к событиям роута и обновляем данные на каждый тик:

ts
const { tick } = interval({ ms: 15_000, start: ordersOpened, stop: ordersClosed, leading: true });

reaction({ on: tick, run: () => void refreshOrdersFx() });

С leading: true первый тик происходит сразу при старте — экран загружает данные немедленно и дальше держит их свежими. Если сеть бывает медленнее интервала, проверяйте refreshOrdersFx.pending.value в реакции, чтобы не наслаивать запросы.

Автосохранение по часам

ts
const { tick } = interval({ ms: 30_000, start: editingStarted, stop: editingStopped });

reaction({ on: tick, run: () => void saveDraftFx(draft.value) });

Если хочется «сохранить, когда пользователь замолчал» — это debounce. Interval — про «сохранять каждые полминуты, что бы ни происходило».

Когда пригодится

  • Таймеры, секундомеры и обратные отсчёты, которые видит пользователь.
  • Поллинг, чьё время жизни принадлежит модели (роут открыт — роут закрыт), а не маунту компонента.
  • Повторяющаяся фоновая работа, пока включён режим: автосохранение, presence-пинги, обновление токена.

Поведение

  • У каждого скоупа свой отсчёт. start в одном скоупе тикает только там; active равен true только там же. Два теста не делят один таймер.
  • start во время работы ничего не делает — не сбрасывает фазу и не ставит второй таймер.
  • Dispose владельца останавливает все скоупы и возвращает active в false — после закрытия экрана таймеров-сирот не остаётся.
  • Каждый тик — отдельное обновление; если реакция на tick упала, ошибка попадёт в отчёт, а интервал продолжит идти.