我目前在构建 NodeJS 项目时遇到困难。我关注了几个 YouTube 系列,看到人们使用不同的技术来构建他们的代码。对于我的情况,您建议我采用哪种结构?最佳实践是什么?
我有我的 app.js
,其中包含与 MongoDB 的连接建立、初始化express、bodyParser、pug 作为 View 引擎,最后启动服务器。
我的 router.js
包含所有路由,不幸的是还包含一些中间件代码,我想将其移至它们自己的专用 Controller 中。
models
文件夹包含 MongoDB 的所有架构文件。
// File structure:
.
├─ controllers
| ├─ morticians.js
| ├─ people.js
| └─ pickups.js
├─ models
| ├─ mortician.js
| ├─ person.js
| └─ pickup.js
├─ views
| ├─ elements
| | └─ ..
| ├─ pages
| | ├─ dashboard.pug
| | └─ ..
| └─ layout.pug
├─ app.js
└─ router.js
我们是一家医院,有时有人会死在这里。殡葬师来接他们,但从我们的系统中删除此人的过程尚未自动化。这就是这个网络应用程序的用途。从我们的数据库中提取所有死者,将其显示在网络应用程序中,并在殡葬师来接走该人后立即将其删除。
1. 当请求主页时,它会找到所有人员,然后找到 MongoDB 中的所有殡葬师,最后渲染页面。我可以想象,这不是最佳实践,但如何重构它?
// snippet router.js
const Person= require('./models/person')
const Mortician = require('./models/mortician')
router.get('/', (req, res, next) => {
Person.find({ pickedUp: false }, (err, people) => {
Mortician.find({}, (err, morticians) => {
if (err) return console.log(err);
res.render('pages/dashboard', {
title: 'Dashboard',
persons: people,
morticians: morticians
})
})
})
}
我尝试将 MongoDB 操作移至其 controller
文件中,如下所示。它有效,但我不确定,因为它使用了多个 promise ,并且没有真正简化事情:
// snippet router.js
const ConPeople = require('./controllers/people')
const ConMorticians = require('./controllers/morticians')
router.get('/',
(req, res, next) => {
res.locals.options = { pickedUp: false }
ConPeople.find(req, res, next)
.then((people) => {
res.locals.people = people
next()
})
},
(req, res, next) => {
res.locals.options = {}
ConMorticians.find(req, res, next)
.then((morticians) => {
res.locals.morticians = morticians
next()
})
},
(req, res) => {
res.render('pages/dashboard', {
title: 'Dashboard',
people: res.locals.people,
morticians: res.locals.morticians.reverse()
})
}
)
// snippet controllers/people.js
module.exports = {
find: (req, res, next) => {
return Person.find(res.locals.options)
}
}
2. 在某些情况下,我需要执行命令,例如从 MongoDB 中删除或添加人员。例如,殡葬师来接一个人。我需要将该人的状态设置为 pickedUp = true
,最终添加一个新的殡葬师(如果提供)并向集合 pickups
添加一个新文档。我该如何做到这一点而不必重写相同的行?
最佳答案
有两件事,当组合使用时,会让代码变得更好:
Collection.find
返回一个 Promise。- 要在现代 Javascript 中等待 Promise 解析,请使用
await
您可以使用以下代码:
const Person= require('./models/person')
const Mortician = require('./models/mortician')
router.get('/', async (req, res, next) => {
try {
const persons = await Person.find({ pickedUp: false });
const morticians = await Mortician.find({});
res.render('pages/dashboard', {
title: 'Dashboard',
persons,
morticians,
});
} catch(e) {
// handle errors
}
});
或者,要并行而不是串行检索结果,请使用 Promise.all
:
router.get('/', async (req, res, next) => {
try {
const [persons, morticians] = await Promise.all([
Person.find({ pickedUp: false }),
Mortician.find({})
]);
res.render('pages/dashboard', {
title: 'Dashboard',
persons,
morticians,
});
} catch(e) {
// handle errors
}
});
每当需要进行多个异步调用时,您都可以使用相同类型的模式 - 无需丑陋的括号嵌套和缩进。
关于node.js - 使用路由、 Controller 和模型重构 NodeJS 项目的中间件代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61726347/