Метод resolve

Метод resolve является ключевым инструментом библиотеки Universal Router для обработки маршрутов в JavaScript. Он отвечает за поиск подходящего маршрута среди заданных правил и выполнение соответствующего обработчика. Его функциональность охватывает синхронное и асинхронное разрешение маршрутов, поддержку вложенных маршрутов, динамических сегментов и различных вариантов обработки ошибок.


Синтаксис и базовое использование

const router = new UniversalRouter(routes);

router.resolve({ pathname: '/users/42' })
  .then(result => console.log(result));
  • routes — массив объектов маршрутов, каждый из которых содержит:

    • path — шаблон пути, например '/users/:id'
    • action — функция, которая выполняется при совпадении маршрута
    • children — массив вложенных маршрутов (опционально)

Метод resolve принимает либо объект с ключом pathname, либо строку пути напрямую:

router.resolve('/about')
  .then(result => console.log(result));

Результат выполнения метода — значение, возвращаемое функцией action маршрута. Если маршрут не найден, по умолчанию метод возвращает undefined.


Обработка динамических сегментов

Маршруты Universal Router поддерживают динамические сегменты, которые определяются двоеточием перед именем параметра:

const routes = [
  {
    path: '/users/:id',
    action: ({ params }) => `User ID: ${params.id}`
  }
];

router.resolve('/users/42').then(console.log); // User ID: 42
  • params — объект, автоматически передаваемый в action, содержащий значения динамических сегментов.
  • Можно использовать несколько сегментов: /users/:userId/posts/:postId.

Вложенные маршруты

Метод resolve рекурсивно проверяет вложенные маршруты, что позволяет строить сложные структуры навигации:

const routes = [
  {
    path: '/users',
    action: () => 'Users list',
    children: [
      {
        path: ':id',
        action: ({ params }) => `User ${params.id}`
      }
    ]
  }
];

router.resolve('/users/7').then(console.log); // User 7
  • Вложенные маршруты могут использовать параметры родительских маршрутов.
  • Вложенность позволяет делить маршруты на логические блоки, например, /admin, /admin/settings.

Асинхронные действия и промисы

Метод resolve полностью поддерживает асинхронные action:

const routes = [
  {
    path: '/data/:id',
    action: async ({ params }) => {
      const response = await fetch(`/api/data/${params.id}`);
      return response.json();
    }
  }
];

router.resolve('/data/5').then(data => console.log(data));
  • Можно возвращать промисы, async функции или синхронные значения.
  • Universal Router автоматически распознаёт промисы и возвращает результат после их разрешения.

Контекст и дополнительная информация

Метод resolve принимает второй необязательный параметр context, который передается во все функции action:

const routes = [
  {
    path: '/dashboard',
    action: ({ context }) => `Welcome, ${context.user}`
  }
];

const context = { user: 'Alice' };
router.resolve('/dashboard', context).then(console.log); // Welcome, Alice
  • context позволяет передавать глобальные данные, такие как авторизация, настройки или состояние приложения.
  • Доступ к context есть на всех уровнях вложенности маршрутов.

Обработка ошибок и несуществующих маршрутов

Если маршрут не найден, метод resolve по умолчанию возвращает undefined. Для обработки ошибок можно определить маршрут с path: '(.*)' или использовать catch:

const routes = [
  {
    path: '/home',
    action: () => 'Home'
  },
  {
    path: '(.*)',
    action: () => 'Page Not Found'
  }
];

router.resolve('/unknown').then(console.log); // Page Not Found
  • Это позволяет создавать страницы 404 и настраивать универсальное поведение для всех неопределённых маршрутов.
  • Любые ошибки, выброшенные в action, будут переданы в catch промиса.

Настройка приоритетов маршрутов

Порядок маршрутов в массиве влияет на приоритет при разрешении:

const routes = [
  { path: '/users/:id', action: () => 'Dynamic user' },
  { path: '/users/admin', action: () => 'Admin panel' }
];

router.resolve('/users/admin').then(console.log); // Dynamic user
  • В данном примере /users/:id захватывает /users/admin.
  • Чтобы исправить приоритет, нужно ставить более конкретные маршруты выше в массиве:
const routes = [
  { path: '/users/admin', action: () => 'Admin panel' },
  { path: '/users/:id', action: () => 'Dynamic user' }
];

router.resolve('/users/admin').then(console.log); // Admin panel

Использование с регулярными выражениями

Путь маршрута можно задать с помощью регулярного выражения для гибкой фильтрации:

const routes = [
  {
    path: /^\/product\/(\d+)$/,
    action: ({ params }) => `Product ID: ${params[0]}`
  }
];

router.resolve('/product/123').then(console.log); // Product ID: 123
  • При использовании RegExp параметры передаются в массив params.
  • Это удобно для сложных или нетипичных URL.

Оптимизация и кэширование

Метод resolve можно комбинировать с кэшированием результатов, чтобы избежать повторного вычисления одного и того же маршрута. Например:

const cache = new Map();

async function cachedResolve(path) {
  if (cache.has(path)) return cache.get(path);
  const result = await router.resolve(path);
  cache.set(path, result);
  return result;
}

cachedResolve('/users/42').then(console.log);
  • Особенно полезно при асинхронных действиях с запросами на сервер.
  • Позволяет улучшить производительность крупных приложений с большим количеством маршрутов.

Метод resolve является основой построения маршрутизации в Universal Router. Его гибкость, поддержка динамических сегментов, вложенных маршрутов, асинхронных действий и контекста делают его идеальным инструментом для создания сложной навигационной логики в современных JavaScript-приложениях.