Node.js 节点中间件在继续之前等待功能完成
我正在节点中导出此函数,但我需要Booking.find函数在其余代码继续之前完成 原件:Node.js 节点中间件在继续之前等待功能完成,node.js,mongoose,async-await,Node.js,Mongoose,Async Await,我正在节点中导出此函数,但我需要Booking.find函数在其余代码继续之前完成 原件: module.exports = function() { return function secured(req, res, next) { if (req.user) { const mongoose = require('mongoose'); const Booking = mongoose.model('Booking');
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');
};
};
我试图用回调创建单独的函数,但我认为这不正确,因为这将是一种异步方法,但我相信我需要使这部分同步
然后我在下面的async await中尝试了这个方法,似乎每次都能正确返回
更新:
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');
};
};
在这种情况下,Wait和middelware对每个页面请求的使用是否正确?我是否可以安全地假设,在Booking.find promise解决之前,页面不会加载
按照建议尝试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);
可使用的尝试:
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');
};
};
在更新的代码中,您都试图使用wait和callback 为了捕获wait中的错误,我们需要使用try-catch块 因此,您可以像这样重写函数: const mongoose=所需的mongoose; const Booking=mongoose.modelBooking; module.exports=函数{ 返回异步函数securedreq,res,next{ 如果需要用户{ 让医生来; 试一试{ docs=等待预订。查找; const bookingsCount=docs.length; const userProfile=req.user; res.locals={ 计数:预订计数, userProfile:JSON.stringifyuserProfile,null,2, 名称:userProfile.displayName, loggedInEmail:userProfile.emails[0]。值, isAuthenticated:req.isAuthenticated }; 下一步返回; }犯错误{ console.logerr; 返回nexterr; } } req.session.returnTo=req.originalUrl; res.redirect/login; }; }; 为了解决原始代码中的问题,您需要将res.locals相关的代码像这样移动到Find回调中,这样它只能在Find工作后工作 module.exports=函数{ 返回函数securedreq,res,next{ 如果需要用户{ const mongoose=所需的mongoose; const Booking=mongoose.modelBooking; Booking.finderr,docs=>{ bookingsCount=docs.length; const userProfile=req.user; res.locals={ 计数:预订计数, userProfile:JSON.stringifyuserProfile,null,2, 名称:userProfile.displayName, loggedInEmail:userProfile.emails[0]。值, isAuthenticated:req.isAuthenticated }; 下一步返回; }; 下一个 } req.session.returnTo=req.originalUrl; res.redirect/login; }; }; 更新: 在模式代码之后,您需要在booking中导出模型,如下所示: module.exports=mongoose.model'Booking',bookingSchema; 并在函数中按如下方式导入: const Booking=需要../型号/预订//TODO:更新您的路径 而不是这一行: const Booking=mongoose.modelBooking;
谢谢你们,太好了,我明白你们的逻辑,try can catch,但实现你们的代码片段会产生预订并没有定义-我在我的问题中添加了我的实现尝试。@ZADorkMan最好在定义预订模式时导出预订模型,你能把模式代码添加到问题中吗?这样我就可以显示该怎么做了。@ZADorkMan我在我的答案末尾做了一个更新,你能做些更改然后再试吗?啊哈,当然,我忘了添加模型调用。但我添加了const mongoose=require'mongoose';const Booking=mongoose.model'Booking';在if req.user{的下方,它似乎可以工作,但如果我可以问,为什么建议更新模型导出?@ZADorkMan使用mongoose.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');
};
};