Node.js 节点中间件在继续之前等待功能完成

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');

我正在节点中导出此函数,但我需要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');
    };
    };
我试图用回调创建单独的函数,但我认为这不正确,因为这将是一种异步方法,但我相信我需要使这部分同步

然后我在下面的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');
    };
    };