【问题标题】:Unable to get object's properties when using async await使用异步等待时无法获取对象的属性
【发布时间】:2018-07-20 20:34:41
【问题描述】:

我正在使用 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 中的行为方式相同。这是一个简化的例子。

【问题讨论】:

  • 我也在通过将对象发送到视图来检查这一点。它在视图中的行为方式与在 console.log 中的行为方式相同。这是一个简化的例子。
  • @Isaac - 我不这么认为,这似乎主要是混淆了 await 的使用方式。

标签: javascript node.js asynchronous async-await


【解决方案1】:

在你的第一个例子中:

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

...您将 promise 对象本身存储在postingseekers 中,然后从posting 中的promise 中获取属性applications。 Promise 没有名为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

...您再次将 promise 存储在 posting 中,但随后在执行日志时等待该承诺,因此 resolution 值 进入 @987654339 @。但是posting 仍然指的是promise,而不是它的结果,所以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})
]);

【讨论】:

  • 哦,好的。现在这是有道理的。谢谢!
  • 还有一个注意事项。您忘记了最后一个示例中的结束语。我无法编辑它,因为我需要更改 6 个字符;)
  • @AlexIronside - 谢谢,已修复。
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 2019-07-29
相关资源
最近更新 更多