【问题标题】:'cannot read _id of undefined' Mongoose promises .then()'无法读取未定义的 _id' Mongoose 承诺 .then()
【发布时间】:2018-08-17 04:19:22
【问题描述】:

我正在为猫鼬的承诺而苦苦挣扎,我需要查询数据并以该数据作为参数查询其他数据

我现在在做什么:

var user_id;
var service_id;
var purpose_id;

User.findOne({name : 'demo1'}).exec().then(function(user){
    user_id = user._id;
    console.log('user')
    return Service.findOne({name : 'JollyClick'}).exec();

}).then(function(service){
    service_id = service._id;
    console.log('service')
    return Purpose.findOne({name : 'Newsfeed'}).exec(function(err, result){
        if(err) console.log(err)
    });
}).then(function(purpose){
    purpose_id = purpose._id
    console.log('purpose')
    DataUse.create({user : user_id, service : service_id, purpose : purpose_id}, function(err, datause){
        if(err) console.log(err)
    })

})

前 2 个 'then' 的值正确返回,但它为 purpose_id 抛出错误,说它未定义,它不明白为什么,我整天都遇到同样的问题,在某些时候我修复了其中一个更改分号,但我不知道它为什么会起作用...

我检查了一个简单的查询

Purpose.findOne({name : 'Newsfeed'}).exec(function(err, result){
    if(err) console.log(err)
});

确实返回结果

顺便说一句,我正在使用猫鼬和蓝鸟作为承诺

请帮忙! 谢谢

【问题讨论】:

  • 可能你这里有问题` return Purpose.findOne({name : 'Newsfeed'}).exec(function(err, result){ if(err) console.log(err) }) ;` 只需返回 .exec() 并在链的末尾使用单个 .catch
  • 非常感谢您的回答,我的代码就是这样,我添加了错误处理以获得解释,这是我知道“目的”未定义的唯一方法,当我捕获时(或者在每个 exec 之后或最后)它没有向我显示任何我会查看的内容 async await 看起来它可以为我节省很多麻烦

标签: javascript node.js mongoose promise bluebird


【解决方案1】:

当您将回调函数传递给.exec 时,它不再返回承诺(或任何与此相关的内容)。这就是为什么 purpose 未定义的原因。

由于您已经在使用 Promise,您可以链接 .catch 来处理错误。

return Purpose.findOne({name : 'Newsfeed'}).exec().catch(err => console.error(err));

如果您需要细粒度的错误处理,您可以这样做,但如果您想捕获链中的任何错误,也可以将 .catch 链接到整个 Promise 链。


根据您所处的环境,您可能可以使用async/await,尤其是对于 node.js 7.10 或更高版本。

async function createDateForUser() {
  const [{ _id: user }, { _id: service }, { _id: purpose }] = await Promise.all([
    User.findOne({name : 'demo1'}).exec(),
    Service.findOne({name : 'JollyClick'}).exec(),
    Purpose.findOne({name : 'Newsfeed'}).exec(),
  ]);

  return DateUse.create({ user, service, purpose }).exec();
}

【讨论】:

  • 非常感谢您的回答,我的代码就是这样,我添加了错误处理以获得解释,这是我知道“目的”未定义的唯一方法,当我捕获时(或者在每个 exec 之后或最后)它没有向我显示任何我会查看的内容 async await 看起来它可以为我省去很多麻烦
  • 请问这些功能的文档是什么?
  • 在定义异步函数“语法错误:令牌函数意外”时,我在节点 v9 中遇到错误,您知道是什么原因造成的吗?
【解决方案2】:
var user_id;
var service_id;
var purpose_id;

User.findOne({name : 'demo1'}).exec().then(function(user){
    user_id = user._id;
    console.log('user')
    return Service.findOne({name : 'JollyClick'}).exec();

}).then(function(service){
    service_id = service._id;
    console.log('service')
    return Purpose.findOne({name : 'Newsfeed'}).exec();
}).then(function(purpose){
    purpose_id = purpose._id
    console.log('purpose')
    return DataUse.create({user : user_id, service : service_id, purpose : purpose_id}).exec()

})
.catch((err)=>console.log(err))

像这样你只需在链的末尾添加catch,这样如果任何承诺被拒绝,它将被缓存在最后

【讨论】:

  • 非常感谢您的回答,我的代码就是这样,我添加了错误处理以获得解释,这是我知道“目的”未定义的唯一方法,当我捕获时(或者在每个 exec 之后或最后)它没有向我显示任何我会查看的内容 async await 看起来它可以为我省去很多麻烦
猜你喜欢
  • 1970-01-01
  • 2019-04-23
  • 2017-01-23
  • 2017-07-19
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
  • 1970-01-01
  • 2019-03-25
相关资源
最近更新 更多