我正在使用Node.js和猫鼬,但是这个问题纯粹是关于async
await
部分。我写了这段代码,它可以正常工作。
router.get('/applications/:_id', async (req, res, next) => {
var posting = await Posting.findOne({'_id': req.params._id, 'creatorId': req.user._id, 'visible': true}); // await here
var seekers = await Account.find({'accType': 'seeker', 'blocked': false});
console.log(posting.applications) // no await here
// ^^^ this will log the applications array.
res.render('users/employer/applications', {
user: req.user,
title: 'Job applications',
applications: posting.applications,
seekers: await seekers,
})
});
但是,如果我这样做:
router.get('/applications/:_id', async (req, res, next) => {
var posting = Posting.findOne({'_id': req.params._id, 'creatorId': req.user._id, 'visible': true}); // remove await from here
var seekers = Account.find({'accType': 'seeker', 'blocked': false});
console.log(await posting.applications); // add await here
// ^^^ this will log undefined
res.render('users/employer/applications', {
user: req.user,
title: 'Job applications',
applications: await posting.applications,
seekers: await seekers,
})
});
我无法打印出posting.applications
阵列。 (未定义)。
但是我能够像这样打印出整个对象:
router.get('/applications/:_id', async (req, res, next) => {
var posting = Posting.findOne({'_id': req.params._id, 'creatorId': req.user._id, 'visible': true});
// ^^^ remove await from here
var seekers = Account.find({'accType': 'seeker', 'blocked': false});
console.log(await posting); // add await here
// ^^^ this will log the object
console.log(await posting.applications); // this will log undefined
res.render('users/employer/applications', {
user: req.user,
title: 'Job applications',
applications: await posting.applications,
seekers: await seekers,
})
});
我认为await会停止执行代码,直到代码执行完毕。那么,如果对象在那里,为什么我无法获得属性?
[重复说明]我也在通过将对象发送到视图来进行检查。它在视图中的行为与console.log中的行为相同。这是一个简化的示例。
答案 0 :(得分:2)
在您的第一个示例中:
var posting = await Posting.findOne({'_id': req.params._id, 'creatorId': req.user._id, 'visible': true}); // await here
var seekers = await Account.find({'accType': 'seeker', 'blocked': false});
您正在等待Posting.findOne
和Account.find
返回的诺言,并将这些诺言的分辨率值存储在posting
和seekers
中
在第二个示例中:
var posting = Posting.findOne({'_id': req.params._id, 'creatorId': req.user._id, 'visible': true}); // remove await from here
var seekers = Account.find({'accType': 'seeker', 'blocked': false});
console.log(await posting.applications); // add await here
...您要将 promise对象本身存储在posting
和seekers
中,然后从{{ 1}}。承诺没有名为applications
的属性,因此posting
会产生applications
。 posting.applications
输入非承诺值会返回该值本身,因此undefined
给您await
。
在您的第三个示例中:
await posting.applications
...您再次将 promise 存储在undefined
中,但是在执行日志时要等待该承诺,因此 resolution值 var posting = Posting.findOne({'_id': req.params._id, 'creatorId': req.user._id, 'visible': true});
// ^^^ remove await from here
var seekers = Account.find({'accType': 'seeker', 'blocked': false});
console.log(await posting); // add await here
。但是posting
仍然指承诺,而不是其结果,因此console.log
仍然是posting
。
在第三个示例中,您可以执行以下操作:
posting.applications
...但实际上,您的第一个示例很好。
但是,如果您希望undefined
和posting = await posting;
重叠,则可以使用Posting.findOne
:
Account.find