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


2 回复

Nodejs express-mongoose 把取model数据的方法写在res.render里面了,这样合理吗?

在Node.js应用中使用Express和Mongoose时,通常我们会遇到需要从数据库获取数据并在视图中渲染的情况。常见的做法是在路由处理函数中先获取数据,然后再传递给res.render方法。将取数据的操作直接写在res.render内部的做法虽然可行,但可能不是最佳实践。

不合理的方面

  1. 职责分离不明确:将数据获取逻辑直接写在res.render内部会使得路由处理函数的职责变得模糊不清,不易于维护。
  2. 异步问题:如果涉及到异步操作(如数据库查询),直接在res.render内部处理可能会导致回调地狱或者Promise链过长,影响代码可读性和可维护性。
  3. 错误处理:直接在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块处理异步操作中的错误,确保服务器不会因为未处理的异常而崩溃。

这种方式不仅提高了代码的可读性和可维护性,还便于未来扩展或修改。

回到顶部