Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Next() в Express

#nodejs #express


После очередного перечитывания документации Express. В мою голову так и не пришло
понимание функции next(). Прошу вас объяснить мне. Для чего и в каких случаях нужно
использовать next(), что эта функция возвращает? Давайте разберем на простом примере

app.get('/users/:id?', function(req, res, next) {
     var id = req.params.id;
     if (id) {
        // делаем что-то
    } else {
        next();
    }
});


Что делает в данном случае next()
    


Ответы

Ответ 1



Фреймворк Express.js построен на концепции ПО промежуточного уровня (англ. middleware). Суть этого подхода в том, что запрос к каждому ресурсу обрабатывается не одним единственным действием контролера (специально опускаю возможные препроцессоры и прочее), а целым стеком функций. При этом, каждая из этих функций может каким-то образом изменять запрос/ответ и передавать управление следующей функции. Так же, какая-то из функций может сгенерировать конечный ответ и отдать его пользователю, прекращая, тем самым, движение вниз по стеку ПО промежуточного уровня. Связывание элементов ПО промежуточного уровня в Express как раз и осуществляется с помощью функции next. Эта функция может быть использована для двух целей: Передать управление следующей функции в стеке (для этого ф-ция next вызывается без параметров). Сообщить фреймворку об ошибке и передать управление специализированному ПО промежуточного уровня (для этого функции next передается объект ошибки). Если же функция next не вызывается, то это значит, что движение вниз по стеку функций должно быть закончено. Проиллюстрирую все вышесказанное на примере. Типичное приложение на node.js с использованием Express выглядит следующим образом: var app = require('express')(); // Здесь мы будет добавлять к каждому входящему запросу время, // когда он поступил с точностью до миллисекунд. В реальном // приложении здесь может быть код инициализации сессии, // аутентификации, авторизации или чего-то еще. app.use('/', function(req, res, next) { req.initTimestamp = (new Date()).getTime(); // Обратите внимание, функция "next" вызывается БЕЗ ПАРАМЕТРОВ. // Это позволяет предать управление следующему обработчику. next(); }); // Этот обработчик проверяет время, инициализации запроса и, // если количество миллисекунд четное, то он завершается с ошибкой. // В реальных приложениях, это может быть, например, ошибка // соединения с базой данных. app.use('/', function(req, res, next) { if (req.initTimestamp % 2 === 0) { // Обратите внимание, функции "next" передается ОБЪЕКТ ОШИБКИ. // Он будет использован чуть позже. next(new Error('Not today. Sorry.')); } else { // Просто отдаем ответ клиенту. Вызов "next" здесь НЕ НУЖЕН, // все следующие обработчики будут проигнорированы. res.send('The sun is shining. Have a nice day :)'); } }); // А вот здесь мы обрабатываем все те ошибки, что были переданы // как аргументы в функцию "next". Обратите внимание, у обработчика // ЧЕТЫРЕ аргумента. "err" - это тот самый объект ошибки из // предыдущего обработчика. app.use('/', function(err, req, res, next) { // Просто отправляем сообщение об ошибке клиенту. res.send(err.message); // А вместо этого мы вполне могли бы передать управление // СЛЕДУЮЩЕМУ обработчику ошибок, вот так // next(err); });

Комментариев нет:

Отправить комментарий