Порядок выполнения

Navigo — это легковесная библиотека маршрутизации для JavaScript, предназначенная для управления навигацией в одностраничных приложениях (SPA). Основная задача маршрутизатора — отслеживать изменения URL и вызывать соответствующие обработчики. В Navigo порядок выполнения имеет ключевое значение, поскольку он определяет, какой обработчик сработает первым, а какой — последующим.

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

const router = new Navigo('/');

router.on('/user/:id', (params) => {
    console.log('User route', params.id);
});

router.on('/user', () => {
    console.log('All users');
});

router.resolve();

В этом примере маршрут /user/:id сработает перед /user, если URL содержит идентификатор пользователя.


Порядок срабатывания обработчиков

Navigo использует внутреннюю очередь для вызова обработчиков. Порядок выполнения зависит от:

  1. Порядка регистрации маршрутов Первым выполняется обработчик того маршрута, который был зарегистрирован раньше.

  2. Соответствия URL Маршрут выполняется только если URL полностью соответствует шаблону маршрута или удовлетворяет параметрам с :param.

  3. Метода resolve() Этот метод инициирует проверку текущего URL и вызывает все подходящие обработчики в порядке их регистрации.

router.on('/posts/:postId', (params) => {
    console.log('Post', params.postId);
});

router.on('/posts', () => {
    console.log('All posts');
});

// при переходе на /posts/42 будет вызван первый обработчик
router.resolve();

Динамические маршруты и порядок

Динамические сегменты (:param) позволяют захватывать значения из URL. При наличии нескольких динамических маршрутов важно учитывать, что Navigo проверяет маршруты по мере их регистрации, а не по длине или специфичности. Это делает порядок объявления критичным.

router.on('/products/:category/:id', (params) => {
    console.log('Category:', params.category, 'ID:', params.id);
});

router.on('/products/:category', (params) => {
    console.log('Category:', params.category);
});

Если разместить более общий маршрут первым (/products/:category), он перехватит все запросы, включая те, где указан ID, что нарушает логику приложения.


Группы маршрутов и последовательность

Navigo поддерживает группы маршрутов через объектную форму:

router.on({
    '/about': () => console.log('About page'),
    '/contact': () => console.log('Contact page')
});

В случае использования объектов порядок следования не гарантируется, так как свойства объекта не имеют строгой последовательности. Для критических маршрутов рекомендуется использовать метод on с отдельными вызовами.


Методы навигации и их влияние на порядок

Методы navigate() и resolve() напрямую влияют на порядок выполнения:

  • navigate(path) — изменяет URL и вызывает обработку маршрутов. Порядок срабатывания такой же, как и при обычной регистрации.
  • resolve() — проверяет текущий URL и выполняет подходящие обработчики. Полезно для инициализации маршрутов при загрузке страницы.
router.navigate('/posts/42'); // вызовет обработчик '/posts/:postId'

Если нужно принудительно вызвать обработчик для текущего URL после динамических изменений, следует использовать router.resolve().


Обработка нескольких совпадений

Navigo поддерживает множественные совпадения маршрутов через массив функций:

router.on('/dashboard', [
    () => console.log('Handler 1'),
    () => console.log('Handler 2')
]);

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


Использование хуков и порядок выполнения

Navigo предоставляет хуки before и after для управления потоком выполнения:

router
  .on('/profile', () => console.log('Profile loaded'))
  .before((done, params, route) => {
      console.log('Before route', route.url);
      done(); // продолжить выполнение
  })
  .after((params, route) => console.log('After route', route.url));
  1. Хук before выполняется перед вызовом основного обработчика маршрута.
  2. Основной обработчик вызывается только после завершения before.
  3. Хук after срабатывает после завершения всех обработчиков маршрута.

Использование хуков позволяет контролировать последовательность и встраивать проверку авторизации, загрузку данных или анимации переходов.


Влияние notFound на порядок

Маршрут notFound срабатывает, если ни один из зарегистрированных маршрутов не соответствует текущему URL:

router.notFound(() => console.log('Page not found'));

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


Резюме по порядку выполнения

  • Первым срабатывает обработчик маршрута, зарегистрированный первым, если URL подходит.
  • Динамические маршруты должны располагаться перед общими, чтобы избежать перехвата.
  • Методы navigate и resolve инициируют проверку и вызов маршрутов.
  • Множественные обработчики одного маршрута выполняются по порядку внутри массива.
  • Хуки before и after позволяют вмешиваться в порядок выполнения до и после основного обработчика.
  • notFound выполняется только после всех зарегистрированных маршрутов.

Правильная организация маршрутов и понимание последовательности вызова обработчиков критично для стабильной работы приложения с Navigo.