【发布时间】:2017-02-04 03:43:28
【问题描述】:
我正在尝试使用 Node.js Express 创建 MVC 模式,但这在执行异步代码时似乎是一项非常不可能的任务。
例如:我从模型中的 NeDB 数据库中获取结果,如下所示:
controllers/database.js
// Database management stuff with NeDB
var data = {};
db.findOne({ _id: 1 }, (error, doc) => {
if (error) console.error(error);
data = doc;
}
现在,我将在一个名为 dbcontroller.js 的控制器中使用它:
var nedb = require('../models/nedb.js');
module.exports.list = function(req, res, next) {
res.render('listpage', {
data: nedb.data,
});
在 routes/routes.js 文件中:
var express = require('express');
var router = express.Router();
var dbcontroller = require('../controllers/dbcontroller.js');
// Other controllers...
router.get('/list', dbcontroller.list);
// Other route definitions...
module.exports = router;
很可爱的安排,不是吗? 现在,果然,NeDB 的 findOne() 函数是异步的,所以它会在 module.exports 之后执行,而那是不行的。想到的解决方案当然是将 module.exports 定义放在 findOne() 回调中!
db.findOne({ _id: 1 }, (error, doc) => {
if (error) console.error(error);
module.exports.data = data;
}
我确定这是某个地方的反模式,但它确实有效。或者是吗?真正的戏剧现在开始。
当它被控制器调用时,findOne() 函数也会在所有控制器逻辑之后完成,这意味着 nedb.data 将是未定义的。我现在必须做一些疯狂的特技......
database.js
module.exports.execute = function (callback) {
db.findOne({ _id: 1 }, (error, doc) =>
{
if (error) console.error(error);
module.exports.data = doc;
callback();
});
}
dbcontroller.js:
nedb.execute(export);
function export() {
module.exports.list = function(req, res, next) {
res.render('listpage', {
data: nedb.data,
});
};
};
而且情况变得更糟。 routes.js 文件现在找不到 dbcontroller.list,大概是因为它仍然是在 之后定义的路线要求它。现在,我是否也必须开始将路由定义放入回调中?
我的意思是,整个异步性似乎完全接管了我的代码结构。以前整洁的代码现在变得一团糟,因为我无法将代码放在它所属的地方。这只是 一个 异步函数,NeDB 有很多异步函数,虽然这很棒,但如果 findOne() 已经让我很头疼,我不知道我是否能处理它。
也许我真的别无选择,我必须弄乱我的代码才能让它工作?或者也许我错过了一些非常基本的东西?或者也许像 async 或 promises 这样的库会做我正在寻找的东西?你怎么看?
【问题讨论】:
标签: node.js express asynchronous