У меня есть маршрут, который загружает список квартир и отображает их:
app.get( '/condo-list', middleware.loadCondoList, routes.views.condolist );
Промежуточное ПО loadCondoList вызывает модель CondoBuilding и устанавливает результаты в res.locals:
exports.loadCondoList = function loadCondoList( req, res, next ) {
console.log( 'request url: ' + req.url );
console.log( 'getting condo buildings...' );
CondoBuilding.model
.find()
.exec( ( err, condos ) => {
if ( err ) {
// pass error along
next( err );
} else {
// add CondoBuildings to locals
res.locals.condoBuildings = condos;
next();
}
});
};
Вызов базы данных выполнен успешно, и страница отображается должным образом. Однако по какой-то причине маршрут проходит дважды. Вывод консоли выглядит следующим образом:
request url: /condo-list
getting condo buildings...
GET /condo-list 304 344.532 ms
request url: /condo-list
getting condo buildings...
GET /condo-list 304 317.631 ms
Я воспроизвел это поведение в нескольких браузерах (Chrome, Safari, Firefox) и убедился, что это не происходит ни на каких других маршрутах.
Если я удаляю вызов CondoBuilding.model.find()
и просто вызываю next()
в теле loadCondoList()
, такого поведения не происходит.
Я использую Keystone 4 "keystone": "4.0.0-beta.5"
, который использует Express 4 "express": "4.14.0"
Ниже приведен полный список маршрутов, которые я запускаю в приложении, если это уместно:
// Setup Route Bindings
exports = module.exports = function ( app ) {
// Views
app.get( '/', routes.views.index );
app.get( '/condo-list', middleware.loadCondoList, routes.views.condolist );
app.get( '/blog/:category?', routes.views.blog );
app.get( '/blog/post/:post', routes.views.post );
app.get( '/about', routes.views.about );
app.get( '/search', middleware.getAccountType, routes.views.search );
app.all( '/contact', routes.views.contact );
};
Представление CondoList:
var keystone = require('keystone');
exports = module.exports = function (req, res) {
var view = new keystone.View(req, res);
var locals = res.locals;
// locals.section is used to set the currently selected
// item in the header navigation.
locals.section = 'condolist';
// Render the view
view.render('condolist');
};
Я отлаживал эту проблему некоторое время, но я не понимаю, что может быть причиной этого. Любая помощь будет оценена по достоинству.
ОБНОВЛЕНИЕ
Я последовал совету @phuhgh и запустил приложение в режиме экспресс-отладки. Хотя сразу ничего не бросалось в глаза, я заметил кое-что странное во время запуска приложения.
Вот последовательность нескольких подготовленных маршрутов, которые ведут себя нормально:
express:router:layer new / +0ms
express:router:route new /blog/post/:post +0ms
express:router:layer new /blog/post/:post +0ms
express:router:route get /blog/post/:post +0ms
express:router:layer new / +0ms
express:router:route new /about +0ms
express:router:layer new /about +0ms
express:router:route get /about +0ms
express:router:layer new / +0ms
express:router:route new /search +1ms
express:router:layer new /search +0ms
express:router:route get /search +0ms
Вот последовательность подготовки маршрута списка квартир:
express:router:layer new / +0ms
express:router:route new /condo-list +0ms
express:router:layer new /condo-list +0ms
express:router:route get /condo-list +0ms
express:router:layer new / +0ms
express:router:route get /condo-list +0ms
Как вы могли заметить, строка express:router:route get /condo-list +0ms
повторяется. Я понятия не имею, почему, но я предполагаю, что это как-то связано с проблемой, с которой я сталкиваюсь. Я немного больше копаюсь в этом вопросе, но опять же, любая помощь от кого-то, у кого есть немного больше знаний в этой области, будет очень признательна.
Обновление 2 – трассировка стека
Я отладил и прошел через стек шаг за шагом. Я могу проследить путь от функции к функции, и все кажется нормальным, но мой базовый уровень нормальности — это поиск других маршрутов, которые работали правильно. Честно говоря, я бы не знал, что искать, если бы я так глубоко погрузился в внутренности Express.
Наблюдения, которые я сделал, просматривая стек:
- Трассировка стека одинакова при обоих запусках маршрута
/condo-list
. - Трассировка стека (конечно, за вычетом промежуточного ПО loadCondoList) точно такая же для других маршрутов, которые выполняются правильно (т.е. только один раз).
- If I add a call to loadCondoList in another route, it also runs properly.
- e.g. I updated the
/about
route definition to the following:app.get( '/about', middleware.loadCondoList, routes.views.about );
and it loads the data properly and only runs once.
- e.g. I updated the
Есть ли что-то, на что мне следует обратить особое внимание, когда я прохожу код библиотеки Express? Я чувствую себя немного не в своей тарелке и не знаю, что искать.