我正在创建快速应用程序,在路由器中我将从mongodb获取数据。这是我的代码
router.get('/', function(req, res, next) {
MongoClient.connect(url, function(err, db) {
db.collection('school').find({}).toArray(function(err, doc) {
assert.equal(null, err);
assert.ok(doc != null);
res.render('index', { title: 'iGyan.org', schools: doc});
});
db.collection('students').find({}).toArray(function(err, doc) {
assert.equal(null, err);
assert.ok(doc != null);
res.render('index', { title: 'iGyan.org',students: doc});
});
db.close();
});
});
当我运行代码并在浏览器中打开一个网址时,它会在控制台上显示错误
Error: Can't set headers after they are sent.
我已经看到几乎所有关于堆栈溢出的建议问题,但是无法从中获得帮助。
我知道错误是因为我在函数中渲染res两次但不知道如何克服这种情况。
答案 0 :(得分:2)
由于db调用是异步的,因此您需要确保它们在呈现响应之前都已完成。基于that answer,您可以使用async lib来完成此任务。
您只能像这样呈现响应一次:
router.get('/', function(req, res, next) {
MongoClient.connect(url, function(err, db) {
var data = {};
var tasks = [
// Load users
function(callback) {
db.collection('school').find({}).toArray(function(err, doc) {
if (err) return callback(err);
data.schools = doc;
callback();
});
},
// Load colors
function(callback) {
db.collection('students').find({}).toArray(function(err, doc) {
if (err) return callback(err);
data.students: doc;
callback();
});
}
];
//This function gets called after the two tasks have called their "task callbacks"
async.parallel(tasks, function(err) {
//If an error occurred, let express handle it by calling the `next` function
if (err) return next(err);
db.close();
res.render('index', {
title: 'iGyan.org',
students: data.students,
schools: data.schools
});
});
});
});
来源:Fetch from multiple, separate, collections with Express and MongoDB