Хук page.exit() в библиотеке Page.js предназначен для
выполнения логики при покидании текущего маршрута. Он позволяет
перехватить момент перехода с одной страницы (роута) на другую и
выполнить необходимые действия до окончательного завершения
навигации.
Это особенно важно в случаях, когда требуется:
page.exit(path, callback)
Параметры:
path — строка маршрута, с которого осуществляется
выходcallback — функция, выполняемая при покидании
маршрутаpage('/profile', function(ctx) {
console.log('Вход в профиль');
});
page.exit('/profile', function(ctx) {
console.log('Выход из профиля');
});
При переходе с /profile на любой другой маршрут будет
вызван обработчик page.exit.
ctx в
page.exit()В колбэке доступен объект контекста ctx, аналогичный
тому, что используется в обычных маршрутах:
page.exit('/dashboard', function(ctx) {
console.log(ctx.path);
console.log(ctx.params);
});
Это позволяет:
При переходе между маршрутами порядок выполнения следующий:
exit-хуки текущего маршрутаЭто означает, что page.exit() выполняется до
загрузки следующего маршрута, но после начала
перехода.
exitМожно определить несколько обработчиков для одного маршрута:
page.exit('/settings', function(ctx) {
console.log('Очистка данных');
});
page.exit('/settings', function(ctx) {
console.log('Удаление событий');
});
Они будут выполнены последовательно в порядке объявления.
page.exit() не поддерживает асинхронную блокировку
перехода напрямую. Если в обработчике выполняется асинхронный код,
переход всё равно произойдет без ожидания завершения:
page.exit('/editor', function(ctx) {
setTimeout(() => {
console.log('Сохранение завершено');
}, 1000);
});
В подобных случаях необходимо самостоятельно управлять логикой перехода, например:
Частый сценарий — удаление слушателей событий:
function onResize() {
console.log('resize');
}
page('/page', function() {
window.addEventListener('resize', onResize);
});
page.exit('/page', function() {
window.removeEventListener('resize', onResize);
});
Это предотвращает утечки памяти и дублирование обработчиков.
let interval;
page('/timer', function() {
interval = setInterval(() => {
console.log('tick');
}, 1000);
});
page.exit('/timer', function() {
clearInterval(interval);
});
Без очистки таймер продолжит работать даже после смены маршрута.
page('/modal', function() {
document.getElementById('modal').style.display = 'block';
});
page.exit('/modal', function() {
document.getElementById('modal').style.display = 'none';
});
page.exit() удобно использовать для сброса визуального
состояния интерфейса.
page('/user/:id', function(ctx) {
console.log('Просмотр пользователя', ctx.params.id);
});
page.exit('/user/:id', function(ctx) {
console.log('Покидание пользователя', ctx.params.id);
});
Параметры маршрута доступны так же, как и в обычных обработчиках.
В отличие от стандартных middleware-функций Page.js:
page.exit() — при выходе из маршрутаЭто делает его аналогом “hook cleanup” в других архитектурах.
1. Ожидание асинхронного завершения
page.exit('/form', async function(ctx) {
await saveData(); // не остановит переход
});
2. Неправильный путь
page.exit('form', function() {}); // ошибка — отсутствует /
3. Забытая очистка Отсутствие exit-хука
при работе с:
page('/chat', loadChat, renderChat);
page.exit('/chat', function() {
disconnectWebSocket();
});
Здесь:
loadChat и renderChat — обработка
входаpage.exit() — завершение соединенияlet unsaved = false;
page('/editor', function() {
window.addEventListener('input', () => {
unsaved = true;
});
});
page.exit('/editor', function() {
if (unsaved) {
console.log('Есть несохранённые изменения');
}
});
В реальном приложении сюда может добавляться:
page.exit() играет ключевую роль в управлении жизненным
циклом маршрутов:
Использование page.exit() позволяет приблизить поведение
приложения к полноценной системе управления состоянием с чётким
контролем за жизненным циклом компонентов.