Сигнатуры функций

Сигнатура функции — это формальное описание способа её вызова. Она включает:

  • имя функции;
  • список параметров (их порядок, количество и иногда типы);
  • возможное возвращаемое значение.

В контексте библиотеки Page.js сигнатуры функций определяют, как именно маршруты обрабатывают входящие URL-запросы, какие данные передаются обработчикам и каким образом происходит управление переходами между страницами.


Сигнатура обработчика маршрута

Базовая сигнатура функции-обработчика маршрута в Page.js выглядит следующим образом:

function(ctx, next) { ... }

Где:

  • ctx — объект контекста маршрута;
  • next — функция для передачи управления следующему обработчику.

Объект ctx

Контекст (ctx) — это ключевой элемент, через который передаются все данные о текущем маршруте. Он содержит:

  • ctx.path — полный путь (например, /users/42);
  • ctx.params — параметры маршрута;
  • ctx.querystring — строка запроса;
  • ctx.hash — якорь URL;
  • ctx.state — состояние, переданное через History API.

Пример:

page('/user/:id', function(ctx) {
  console.log(ctx.params.id);
});

Если перейти по адресу /user/10, в консоль будет выведено 10.


Параметр next и цепочки обработчиков

Функция next позволяет выстраивать цепочки middleware, аналогично серверным фреймворкам вроде Express.

Сигнатура:

function(ctx, next)

Использование:

function middleware(ctx, next) {
  console.log('Перед переходом');
  next();
}

function handler(ctx) {
  console.log('Основной обработчик');
}

page('/example', middleware, handler);

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

  1. middleware
  2. вызов next()
  3. handler

Если next() не вызывается, цепочка прерывается.


Сигнатура функции маршрута с несколькими обработчиками

Page.js позволяет передавать несколько функций в один маршрут:

page(path, ...callbacks)

Каждый callback должен соответствовать сигнатуре:

function(ctx, next)

или:

function(ctx)

Если функция не принимает next, она считается конечной.

Пример:

page('/dashboard',
  function(ctx, next) {
    if (!auth) return page('/login');
    next();
  },
  function(ctx) {
    renderDashboard();
  }
);

Сигнатура функции инициализации маршрута

Основная функция page имеет перегруженную сигнатуру:

page(path, callback)
page(path, callback1, callback2, ...)

Также существует форма без указания пути:

page(callback)

В этом случае callback будет выполнен при каждом переходе:

page(function(ctx, next) {
  console.log('Глобальный обработчик');
  next();
});

Сигнатура функции перехода

Для программного перехода используется:

page(path)

или:

page(path, state, dispatch, push)

Где:

  • path — путь для перехода;
  • state — объект состояния;
  • dispatch — немедленный вызов обработчиков;
  • push — добавление записи в историю.

Пример:

page('/about');

Сигнатура функции page.redirect

Перенаправление задаётся следующей сигнатурой:

page.redirect(from, to)

или:

page.redirect(to)

Пример:

page.redirect('/old', '/new');

При переходе на /old автоматически произойдёт переход на /new.


Сигнатура функции page.start

Запуск маршрутизации:

page.start(options)

Параметр options — объект конфигурации:

  • dispatch — выполнять ли текущий маршрут сразу;
  • popstate — слушать ли события истории;
  • click — обрабатывать ли клики по ссылкам.

Пример:

page.start({
  dispatch: true
});

Сигнатура функции page.stop

Остановка маршрутизации:

page.stop()

Используется для отключения всех обработчиков событий.


Пользовательские сигнатуры и расширение

Поскольку Page.js не накладывает строгой типизации, допускается расширение сигнатуры за счёт добавления собственных свойств в ctx.

Пример:

page('*', function(ctx, next) {
  ctx.user = getCurrentUser();
  next();
});

Теперь в любом обработчике доступно:

page('/profile', function(ctx) {
  console.log(ctx.user);
});

Обработка асинхронных функций

Page.js не требует специальной сигнатуры для асинхронных функций, однако важно контролировать вызов next():

page('/data', async function(ctx, next) {
  ctx.data = await fetchData();
  next();
});

Если next() не вызывается после асинхронной операции, выполнение цепочки остановится.


Ошибки при работе с сигнатурами

Наиболее распространённые проблемы:

1. Отсутствие next()

function(ctx, next) {
  // забыли вызвать next()
}

Результат — последующие обработчики не выполняются.

2. Неправильный порядок параметров

function(next, ctx) { ... } // ошибка

Page.js ожидает строго (ctx, next).

3. Использование next в конечном обработчике

function(ctx) {
  next(); // next не определён
}

Практика комбинирования сигнатур

Сложные маршруты строятся через комбинацию различных сигнатур:

page('/admin',
  loadUser,
  checkAdmin,
  renderAdmin
);

function loadUser(ctx, next) {
  ctx.user = getUser();
  next();
}

function checkAdmin(ctx, next) {
  if (!ctx.user.isAdmin) return page('/');
  next();
}

function renderAdmin(ctx) {
  render('admin');
}

Такая структура повторяет паттерн middleware и делает код модульным и расширяемым.


Вывод о роли сигнатур

Сигнатуры функций в Page.js формируют основу маршрутизации:

  • определяют поток выполнения;
  • обеспечивают передачу данных;
  • позволяют строить цепочки middleware;
  • дают гибкость для расширения.

Глубокое понимание сигнатур позволяет проектировать масштабируемые клиентские приложения с чёткой архитектурой маршрутов.