ИМХО, принятый ответ на этот вопрос не совсем точен. Как утверждали другие, на самом деле речь идет об управлении, когда запускается следующий обработчик в цепочке. Но я хотел предоставить немного больше кода, чтобы сделать его более конкретным. Допустим, у вас есть простое экспресс-приложение:
var express = require('express');
var app = express();
app.get('/user/:id', function (req, res, next) {
console.log('before request handler');
next();
});
app.get('/user/:id', function (req, res, next) {
console.log('handling request');
res.sendStatus(200);
next();
});
app.get('/user/:id', function (req, res, next) {
console.log('after request handler');
next();
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});
Если вы это сделаете
curl http://localhost:3000/user/123
вы увидите это на консоли:
before request handler
handling request
after request handler
Теперь, если вы закомментируете вызов next()
в среднем обработчике следующим образом:
app.get('/user/:id', function (req, res, next) {
console.log('handling request');
res.sendStatus(200);
//next();
});
Вы увидите это на консоли:
before request handler
handling request
Обратите внимание, что последний обработчик (тот, который печатает after request handler
) не запускается. Это потому, что вы больше не говорите Express, что нужно запустить следующий обработчик.
Так что на самом деле не имеет значения, был ли ваш «основной» обработчик (тот, который возвращает 200) успешным или нет, если вы хотите, чтобы остальные промежуточные программы работали, вы должны вызвать next()
.
Когда это пригодится? Предположим, вы хотите регистрировать все запросы, поступившие в какую-либо базу данных, независимо от того, был ли запрос успешным.
app.get('/user/:id', function (req, res, next) {
try {
// ...
}
catch (ex) {
// ...
}
finally {
// go to the next handler regardless of what happened in this one
next();
}
});
app.get('/user/:id', function (req, res, next) {
logToDatabase(req);
next();
});
Если вы хотите, чтобы второй обработчик запустился, вы должны вызвать next()
первый обработчик.
Помните, что узел является асинхронным, поэтому он не может знать, когда завершился обратный вызов первого обработчика. Вы должны сказать это по телефону next()
.