Я экспортирую эту функцию в Node, но мне нужно, чтобы функция Booking.find
завершилась до продолжения остальной части кода.
Оригинал:
module.exports = function() {
return function secured(req, res, next) {
if (req.user) {
const mongoose = require('mongoose');
const Booking = mongoose.model('Booking');
Booking.find((err, docs) => { // I need this to run first
bookingsCount = docs.length;
});
const userProfile = req.user;
res.locals = {
count: bookingsCount, // so that when the page loads this var is available
userProfile: JSON.stringify(userProfile, null, 2),
name: userProfile.displayName,
loggedInEmail: userProfile.emails[0].value,
isAuthenticated: req.isAuthenticated(),
};
return next();
}
req.session.returnTo = req.originalUrl;
res.redirect('/login');
};
};
Я пытался создать отдельные функции с обратным вызовом, но я не думаю, что это сработало правильно, потому что тогда это был бы асинхронный подход, но я считаю, что мне нужно сделать эта часть синхронна.
Тогда я попробовал это ниже Как ждать возврата Mon goose search asyn c, ожидают, и кажется будет возвращаться правильно каждый раз .
Обновлено:
module.exports = function () {
return async function secured(req, res, next) { // added async
if (req.user) {
const mongoose = require('mongoose');
const Booking = mongoose.model('Booking');
await Booking.find((err, docs) => { // added await
bookingsCount = docs.length;
});
const userProfile = req.user;
res.locals = {
count: bookingsCount,
userProfile: JSON.stringify(userProfile, null, 2),
name: userProfile.displayName,
loggedInEmail: userProfile.emails[0].value,
isAuthenticated: req.isAuthenticated(),
};
return next();
}
req.session.returnTo = req.originalUrl;
res.redirect('/login');
};
};
Это правильное использование await в таком случае и в промежуточном программном обеспечении для каждого запроса страницы, и могу ли я с уверенностью предположить, что страница не загрузится до Booking.find
обещание решено?
Попытка 1 в соответствии с предложением:
module.exports = function () {
return async function secured(req, res, next) {
if (req.user) {
let docs;
try {
docs = await Booking.find((err, docs) => {
const bookingsCount = docs.length;
const userProfile = req.user;
res.locals = {
count: bookingsCount,
userProfile: JSON.stringify(userProfile, null, 2),
name: userProfile.displayName,
loggedInEmail: userProfile.emails[0].value,
isAuthenticated: req.isAuthenticated(),
};
});
return next();
} catch (err) {
console.log(err);
return next(err);
}
}
req.session.returnTo = req.originalUrl;
res.redirect('/login');
};
};
Бронирование модели по запросу:
const mongoose = require('mongoose');
const bookingSchema = new mongoose.Schema({
firstName: {
type: String,
required: 'This field is required',
},
lastName: {
type: String,
required: 'This field is required',
},
tourType: {
type: String,
required: 'This field is required',
},
dateBooked: {
type: String,
required: 'This field is required',
},
tourDate: {
type: String,
required: 'This field is required',
},
pax: {
type: String,
required: 'This field is required',
},
phone: {
type: String,
required: 'This field is required',
},
customerEmail: {
type: String,
required: 'This field is required',
},
pickupAddress: {
type: String,
required: 'This field is required',
},
operatorName: {
type: String,
required: 'This field is required',
},
paidStatus: {
type: String,
required: 'This field is required',
},
notes: {
type: String,
},
guidesName: {
type: String,
},
guidesEmail: {
type: String,
},
bookingCreatedSent: {
type: Boolean,
},
calendarEventCreated: {
type: Boolean,
},
clientReminderSent: {
type: Boolean,
},
remindOperators: {
type: Boolean,
},
remindGoCapeGuides: {
type: Boolean,
},
feedbackSent: {
type: Boolean,
},
});
// Custom validation for email
bookingSchema.path('customerEmail').validate((val) => {
emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return emailRegex.test(val);
}, 'Invalid e-mail.');
mongoose.model('Booking', bookingSchema);
DB. js - модель зависит
const mongoose = require('mongoose');
require('dotenv').config();
env = process.env.NODE_ENV;
envString = env;
// mongoDB connection string
const url = process.env['MONGO_DB_URL' + envString];
console.log(url);
mongoose.connect(url, {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false})
.then(() => {
console.log('connected!', process.env.PORT || '8000');
})
.catch((err) => console.log(err));
//db.close();
require('./booking.model');
Используемая попытка:
module.exports = function() {
return async function secured(req, res, next) {
if (req.user) {
const Booking = require('../model/booking.model');
let docs;
try {
docs = await Booking.find((err, docs) => {
const bookingsCount = docs.length;
const userProfile = req.user;
res.locals = {
count: bookingsCount,
userProfile: JSON.stringify(userProfile, null, 2),
name: userProfile.displayName,
loggedInEmail: userProfile.emails[0].value,
isAuthenticated: req.isAuthenticated(),
};
});
return next();
} catch (err) {
console.log(err);
return next(err);
}
}
req.session.returnTo = req.originalUrl;
res.redirect('/login');
};
};