繁体   English   中英

从 Express Router 中分离 Mongoose 代码

[英]Separating Mongoose code from Express Router

所以基本上,我试图将处理数据(猫鼬)的代码与我的快速路由器代码分开,因为我可能也想在其他地方使用它。

我做的第一件事是,我摆脱了 res.json() 调用,因为我不希望代码只返回 http 响应。 我希望它返回数据,这样我就可以从我的路由器返回该数据作为 http 响应,但仍将其用作其他地方的常规数据。

这是我写的一个 function 从 mongoose 获取数据。

module.exports.user_login = data => {
    console.log(data);
    ModelUser.findOne({email: data.email}).then(user => {
        if(!user){
            console.log({email: 'E-mail address not found'});
            return {
                status: response_code.HTTP_404,
                response: {email: 'E-mail address not found'}
            }
        }

        bcrypt.compare(data.password, user.password).then(isMatch => {
            if(!isMatch){
                console.log({password: 'Invalid password'});
                return {
                    status: response_code.HTTP_400,
                    response: {password: 'Invalid password'}
                }
            }
                
            const payload = {
                id: user.id,
                email: user.email
            };

            jwt.sign(
                payload,
                config.PASSPORT_SECRET,
                { 
                    expiresIn: "1h"
                },
                (err, token) => {
                    console.log({
                        status: response_code.HTTP_200,
                        response: {
                            success: true,
                            token: token
                        }
                    });
                    return {
                        status: response_code.HTTP_200,
                        response: {
                            success: true,
                            token: token
                        }
                    }
                }
            );
        });
    });
};

当这段代码像这样在我的路线中执行时:

router.post("/login", (req, res) => {
    const { errors, isValid } = validateLogin(req.body);
    if(!isValid) return res.status(400).json(errors);

    console.log("ret", dm_user.user_login(req.body));
    
});

日志显示 user_login() 的返回值未定义,即使就在 user_login() 的返回语句之前我正在记录完全相同的值并且它们正在被记录。

在我将它更改为日志之前,我尝试将返回值存储在一个变量中,但显然它也仍然未定义,并且我收到错误:尝试使用该值时“无法读取未定义的属性‘状态’”。

我肯定错过了什么..

那么你在这里有一个小的回调地狱。 go 使用async / await并将代码拆分为更小的块而不是将所有内容都放在 1 个文件中可能是个好主意。

我重写了你的user_login function:

const { generateToken } = require("./token.js");
module.exports.user_login = async data => {
  let user = await ModelUser.findOne({ email: data.email });
  if (!user) {
    console.log({ email: "E-mail address not found" });
    return {
      status: response_code.HTTP_404,
      response: { email: "E-mail address not found" }
    };
  }

  let isMatch = await bcrypt.compare(data.password, user.password);
  if (!isMatch) {
    console.log({ password: "Invalid password" });
    return {
      status: response_code.HTTP_400,
      response: { password: "Invalid password" }
    };
  }

  const payload = {
    id: user.id,
    email: user.email
  };

  let response = await generateToken(
    payload,
    config.PASSPORT_SECRET,
    response_code
  );
  return response;
};

我已将您的令牌签名方法移至另一个文件并承诺:

module.exports.generateToken = (payload, secret, response_code) => {
  return new Promise((res, rej) => {
    jwt.sign(
      payload,
      secret,
      {
        expiresIn: "1h"
      },
      (err, token) => {
        if (err) {
          rej(err);
        }
        res({
          status: response_code.HTTP_200,
          response: {
            success: true,
            token: token
          }
        });
      }
    );
  });
};

现在您需要将路由器 function 更改为异步:

router.post("/login", async (req, res) => {
    const { errors, isValid } = validateLogin(req.body);
    if(!isValid) return res.status(400).json(errors);

    let result = await dm_user.user_login(req.body);
    console.log(result);
    
});

另外:你得到 undefined 因为你将你的值返回给回调 function

我也会将你的路由与你的控制器分开,而不是在匿名 function 中编写你的代码

请注意,无论何时您尝试返回任何值,您始终出现在回调 function 中,并且绝对不会将任何值返回到其预期位置。

您可以对代码进行一些改进:

1.不要在进行数据库调用的代码中使用 jwt,而是将其移动到定义路由的位置或制作单独的文件。

2.如果您打算重新使用代码,我建议您使用 Ifaruki 上面的答案中所示的 async-await,或者您可以使用 async.js 之类的东西。 但是上面显示的方法更好。

  1. 当你像这样进行数据库调用时,也总是使用“错误”字段:

ModelUser.findOne({email: data.email}).then((error,user) => {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM