我在Node中构建应用程序并使用Mongoose和CosmosDB。我想显示与登录用户关联的公司拥有的所有图表。
我有一个来自Passport.js的用户,我用它来查询数据库以便返回他的公司。返回正常。
我遇到麻烦的地方:一旦我有他的公司,我想再进行第二次查询以获得属于它的所有情节。这应该是带回一个对象数组,但它返回一个空数组。
两个问题:
代码:
app.get('/plots',
requireAuth,
function(req, res) {
let company;
User.find({ email: req.user.email }).lean().exec(function(err, results) {
if (err) {
console.log(err);
}
if (!results) {
res.send(null);
return;
} else {
company = results[0].company;
};
}).then(
PlotCast.find({ owner: company }).lean().exec(function(err, results) {
if (err) {
console.log('error', err);
res.send(err);
} else if (!results) {
res.send(null);
} else {
console.log('results', results);
res.send(results);
}
})
).catch(function(e) {
console.log('error', e);
});
}
)
答案 0 :(得分:2)
实际上为了让它更优雅你应该使用Promises,让我们说bluebird库(或任何其他首选的)
所以当你需要mongoose为它提供一个Promise库时,代码应该看起来更好,更具可读性和顺序性
const mongoose = require('mongoose');
const Promise = require('bluebird');
mongoose.Promise = Promise;
app.get('/plots', requireAuth,
function(req, res) {
User.find({ email: req.user.email }).lean()
.then(function(results) {
if (!results) throw new Error('User not found');
else return results[0].company;
})
.then(function(company) {
return PlotCast.find({ owner: company }).lean();
})
.then(function(results) {
if (!results) throw new Error('Plot Cast not found')
else {
console.log('results', results);
res.send(results);
}
})
.catch(function(e) {
console.log('error', e);
res.status(400).send(e);
});
})
答案 1 :(得分:2)
有一个替代解决方案从来没有坏。
我个人讨厌直接与Promises合作,而更喜欢使用async.js。在您的情况下async.waterfall()会很有用,因为您基本上将结果从一个异步任务传递给下一个异步任务。
app.get('/plots', requireAuth, function(req, res) {
async.waterfall([
function getUser(done) {
// use findOne, not find -- as you only want to retrive ONE user; using find is more expensive
User.findOne({ email: req.user.email }).lean().exec(done);
},
function getCasts(user, done) {
PlotCast.find({ owner: user.company }).lean().exec(done);
},
], function (err, casts) {
// if an error occurs during the above tasks ^, it will come down here
if (err) {
console.log(err);
return res.status(400).send(e);
}
// otherwise if all tasks finish, it will come down here
res.json(casts);
});
});
因此,使用async.js的好处是,您可以将所有错误集中在一个地方,而不是拥有多个地方(根据您的工作情况,这也很好)。
我认为你最初的问题是你一起使用回调和承诺。通常你会使用其中一种。