我正在使用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,
    })
});


我以为,等待会停止执行代码,直到代码执行完毕。那么,如果对象存在,为什么我无法获得属性?

[重复说明]我也在通过将对象发送到视图来检查这一点。它在视图中的行为与console.log中的行为相同。这是一个简化的示例。

最佳答案

在第一个示例中:

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.findOneAccount.find返回的诺言,并将这些诺言的分辨率值存储在postingseekers中。

在第二个示例中:

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


...您正在将承诺对象本身存储在postingseekers中,然后从applications中的承诺中获取属性posting。承诺没有名为applications的属性,因此posting.applications会导致undefinedawait输入非承诺值会返回值本身,因此await posting.applications为您提供undefined

在您的第三个示例中:

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.findOneAccount.find重叠,则可以使用Promise.all

var [posting, seekers] = await Promise.all([
    Posting.findOne({'_id': req.params._id, 'creatorId': req.user._id, 'visible': true}),
    Account.find({'accType': 'seeker', 'blocked': false})
]);

关于javascript - 使用异步等待时无法获取对象的属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51442451/

10-12 13:35