В Universal Router каждая запись маршрута может
содержать асинхронный или синхронный обработчик (action),
который возвращает значение. Механизм выполнения маршрутов основан на
последовательном обходе дерева маршрутов: при совпадении пути роутер
вызывает соответствующий action и переходит к следующему
уровню вложенности. Иногда необходимо прервать дальнейшее
выполнение цепочки, чтобы вернуть результат немедленно или
остановить обработку дочерних маршрутов. Universal Router предоставляет
несколько способов для этого.
Основной способ прерывания цепочки — возврат значения из
функции action. Если функция возвращает не
undefined, выполнение маршрутизации останавливается, и
возвращенное значение становится результатом маршрута.
import UniversalRouter from 'universal-router';
const routes = [
{
path: '/dashboard',
action: () => {
return 'Dashboard загружен';
}
},
{
path: '/profile',
action: () => {
return 'Профиль пользователя';
}
}
];
const router = new UniversalRouter(routes);
router.resolve('/dashboard').then(result => {
console.log(result); // 'Dashboard загружен'
});
Ключевой момент: action автоматически
прерывает цепочку, если возвращает любое значение, отличное от
undefined.
Функция next в action позволяет
передавать управление следующему маршруту. Если
next() вызывается без аргументов, выполнение продолжается,
иначе возвращаемое значение становится результатом маршрута.
const routes = [
{
path: '/user/:id',
action: (context, next) => {
if (context.params.id === 'admin') {
return 'Администратор';
}
return next(); // Продолжаем поиск среди дочерних маршрутов
},
children: [
{ path: '', action: () => 'Обычный пользователь' }
]
}
];
const router = new UniversalRouter(routes);
router.resolve('/user/admin').then(console.log); // 'Администратор'
router.resolve('/user/guest').then(console.log); // 'Обычный пользователь'
Особенность: вызов next() с аргументом
немедленно завершает обработку и возвращает переданное значение.
Для сложных сценариев, где требуется остановка маршрутизации с сообщением об ошибке или особым кодом, можно использовать пользовательские исключения:
class RouteAbort extends Error {
constructor(message) {
super(message);
this.name = 'RouteAbort';
}
}
const routes = [
{
path: '/secret',
action: () => {
throw new RouteAbort('Доступ запрещён');
}
}
];
const router = new UniversalRouter(routes);
router.resolve('/secret')
.then(console.log)
.catch(error => {
if (error instanceof RouteAbort) {
console.error(error.message); // 'Доступ запрещён'
}
});
Такой подход позволяет разделять логическую ошибку маршрута и неудачную маршрутизацию, сохраняя контроль над выполнением цепочки.
Вложенные маршруты также поддерживают прерывание. Если родительский
action возвращает значение, дочерние маршруты не
выполняются:
const routes = [
{
path: '/products',
action: () => 'Список товаров',
children: [
{ path: ':id', action: () => 'Детали товара' }
]
}
];
const router = new UniversalRouter(routes);
router.resolve('/products').then(console.log); // 'Список товаров'
router.resolve('/products/42').then(console.log); // 'Детали товара'
Если в родительском action вернуть значение, вложенный
маршрут не будет вызван:
const routes = [
{
path: '/products',
action: () => 'Прерываем обработку',
children: [
{ path: ':id', action: () => 'Детали товара' }
]
}
];
router.resolve('/products/42').then(console.log); // 'Прерываем обработку'
Universal Router полностью поддерживает прерывание в
асинхронных обработчиках. Если action возвращает
промис, маршрутизация ожидает его разрешения, после чего цепочка может
быть прервана:
const routes = [
{
path: '/load',
async action() {
const data = await fetchData();
if (!data) return 'Данные отсутствуют'; // Прерывание цепочки
return 'Данные загружены';
}
}
];
router.resolve('/load').then(console.log);
return next() для
продолжения маршрутизации только в случаях, когда родительский маршрут
не полностью обработал путь.action — простой
способ остановки маршрутизации.action вернул undefined или вызвал
next().Прерывание цепочки является основным механизмом контроля маршрутизации в Universal Router, позволяя гибко управлять обработкой как простых, так и сложных вложенных маршрутов.