javascript - 从 Express Router 中分离 Mongoose 代码
问题描述
所以基本上,我试图将处理数据(猫鼬)的代码与我的快速路由器代码分开,因为我可能也想在其他地方使用它。
我做的第一件事是,我摆脱了 res.json() 调用,因为我不希望代码只返回一个 http 响应。我希望它返回数据,因此我可以从路由器返回该数据作为 http 响应,但仍将其用作其他地方的常规数据。
这是我编写的用于从 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() 中的 return 语句之前我正在记录完全相同的值并且它们正在被记录。
在我将它更改为日志之前,我尝试将返回值存储在一个变量中,但显然它仍然是未定义的,并且我收到错误:尝试使用该值时无法读取未定义的属性“状态”。
我肯定错过了一些东西..
解决方案
好吧,这里有一个小的回调地狱。async / await
将代码拆分成更小的块而不是将所有内容放在一个文件中可能是个好主意。
我重写了你的user_login
函数:
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
}
});
}
);
});
};
现在您需要将路由器功能更改为异步:
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 因为你将你的值返回给一个回调函数
我还将您的路由与您的控制器分开,而不是在匿名函数中编写代码
推荐阅读
- javascript - 想要使用布尔值显示和隐藏元素 true false
- c# - 按 ID 获取正在运行的任务
- ios - 如何在tableview swift中自动调整标题视图的大小?
- mysql - 当有多个相似项目时,命名表列的最佳方法是什么?
- snowflake-cloud-data-platform - 数据治理 - 分类
- javascript - 无法读取未定义的、没有 ssl 的 Web Crypto API 的属性“importKey”
- apache - Htaccess:URL 重写不会在不存在的页面上导致 404 并且无法按预期工作
- azure-devops - TFS WorkItemStore 正在缓存 WorkItems?
- java - 将 JDK 路径从 WSL2 Ubuntu 添加到 IntelliJ IDE 冻结屏幕
- flutter - Flutter-不可为空的实例字段'questionAnswer','questionText'必须初始化