В Express (и других аналогичных системах) каждый запрос проходит через серию промежуточного программного обеспечения функций (например, cb0
).У каждого из них есть возможность что-то сделать с запросом.
Поскольку функция промежуточного программного обеспечения может быть асинхронной (например, чтение файла, запрос базы данных и т. Д.), Express не может простонапрямую вызвать следующий бит промежуточного программного обеспечения после вызова предыдущего.Таким образом, вместо этого он передает функции промежуточного программного обеспечения функцию next
, которую промежуточное программное обеспечение использует, чтобы сказать: «Я закончил, выполните следующий шаг».(В версии Express вы также можете передать аргумент next
, так как Aikon Mogwai указывает : если вы передадите ему Error
, он вызовет обработку ошибки для маршрута. Если вы передадите его"route"
, он переходит к следующему маршрутизатору и т. Д.).
Таким образом, концепция функции next
не является специфичной для Express, но конкретное использование в этом примере:
Вот очень упрощенный пример не использования Express, а демонстрация того, что он делает с функциями промежуточного программного обеспечения при обработке запроса:
const app = {
middleware: [],
use(callback) {
this.middleware.push(callback);
}
};
app.use((req, res, next) => {
console.log("First handler synchronous part");
setTimeout(() => {
console.log("First handler async part finished");
next();
}, 800);
});
app.use((req, res, next) => {
console.log("Second handler is entirely synchronous");
next();
});
app.use((req, res, next) => {
console.log("Third handler synchronous part");
setTimeout(() => {
console.log("Third handler async part finished");
next();
}, 800);
});
// Code handling an incoming request
function handleRequest(req, app) {
// Copy the handlers
const middleware = app.middleware.slice();
// Create a "response"
const res = {};
// Call the handlers
let index = 0;
next();
function next() {
if (index < middleware.length) {
// Call the handler, have it call `next` when it's done
middleware[index++](req, res, next);
} else {
console.log("Request completed");
}
}
}
handleRequest({}, app);
Вероятно, стоит упомянуть, что этот стиль ручной асинхронной обработки промежуточного программного обеспечения был заменен обещаниями в Koa.js , который являетсяновый (эр) фреймворк от тех же людей, что и Express.js.С помощью Koa вы выполняете свои функции обратного вызова async
, и внутренние компоненты Koa ждут обещания, которое возвращает функция async
для расчета, а затем воздействуют на результат ее установки (например, отклонение или выполнение, значение, которое она выполняет, и т. Д..).