Nodejs express-mongoose 把取model数据的方法写在res.render里面了,这样合理吗?
Nodejs express-mongoose 把取model数据的方法写在res.render里面了,这样合理吗?
app.get(’/dashboard’, function (req, res) {
var News = db.model(‘News’);
// render support
res.render(‘dashboard’, {
likes: req.user.getLikes()
, latestNews: News.getLatest()
, stuff: new Promise(somethingAsync)
});
});
Nodejs express-mongoose 把取model数据的方法写在res.render里面了,这样合理吗?
在Node.js应用中使用Express和Mongoose时,通常我们会遇到需要从数据库获取数据并在视图中渲染的情况。常见的做法是在路由处理函数中先获取数据,然后再传递给res.render
方法。将取数据的操作直接写在res.render
内部的做法虽然可行,但可能不是最佳实践。
不合理的方面
- 职责分离不明确:将数据获取逻辑直接写在
res.render
内部会使得路由处理函数的职责变得模糊不清,不易于维护。 - 异步问题:如果涉及到异步操作(如数据库查询),直接在
res.render
内部处理可能会导致回调地狱或者Promise链过长,影响代码可读性和可维护性。 - 错误处理:直接在
res.render
内部处理数据获取逻辑可能会导致错误处理变得复杂。
合理的改进方式
推荐的做法是在路由处理函数中先完成数据获取,并确保所有异步操作完成后才调用res.render
。可以使用async/await来简化异步代码的编写。
示例代码
假设我们有一个News
模型,并且希望在访问/dashboard
路由时获取最新的新闻条目并渲染到视图中:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
// 假设已经连接到MongoDB数据库
const db = mongoose.connection;
// 定义News模型
const NewsSchema = new mongoose.Schema({
title: String,
content: String,
createdAt: { type: Date, default: Date.now }
});
const News = mongoose.model('News', NewsSchema);
// 异步函数获取最新新闻
async function getLatestNews() {
const latestNews = await News.find().sort({ createdAt: -1 }).limit(5);
return latestNews;
}
// 路由处理函数
app.get('/dashboard', async (req, res) => {
try {
const latestNews = await getLatestNews();
// 渲染视图,并传递数据
res.render('dashboard', {
likes: req.user.getLikes(),
latestNews: latestNews,
stuff: new Promise((resolve, reject) => {
setTimeout(() => resolve('Async Data'), 1000);
})
});
} catch (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
在这个示例中,我们将数据获取逻辑放在一个单独的异步函数getLatestNews
中,这使得路由处理函数更加清晰,易于理解和维护。同时,通过try-catch块处理可能出现的错误,提高了代码的健壮性。
将取model数据的方法写在res.render
里面是可以的,但从代码组织、可维护性和逻辑分离的角度来看,这样做可能不是最佳实践。通常推荐的做法是先从数据库获取所需的数据,然后将这些数据传递给渲染函数。这样可以更好地分离关注点,提高代码的可读性和可维护性。
示例代码
const express = require('express');
const mongoose = require('mongoose');
const app = express();
// 假设你已经连接到MongoDB并定义了一个News模型
const News = mongoose.model('News', new mongoose.Schema({ title: String, content: String }));
app.get('/dashboard', async function (req, res) {
try {
const latestNews = await News.find().sort({ createdAt: -1 }).limit(5); // 获取最新的5条新闻
res.render('dashboard', {
likes: req.user.getLikes(),
latestNews: latestNews,
stuff: new Promise(somethingAsync) // 如果需要异步处理其他数据
});
} catch (error) {
console.error(error);
res.status(500).send('Server Error');
}
});
module.exports = app;
解释
- 代码结构:在路由处理函数中,首先通过异步方法
await News.find()
获取数据。这使得代码更清晰,并且更容易进行错误处理。 - 分离关注点:这种做法将数据获取与视图渲染分开,使得代码更加模块化,也更容易测试。
- 错误处理:通过try-catch块处理异步操作中的错误,确保服务器不会因为未处理的异常而崩溃。
这种方式不仅提高了代码的可读性和可维护性,还便于未来扩展或修改。