'无法读取_id of undefined'猫鼬承诺.then()

时间:2018-03-08 17:50:02

标签: javascript node.js mongoose promise bluebird

我正在接受mongoose承诺,我需要查询数据并使用该数据查询其他数据作为参数

我现在在做什么:

x

正确返回前两个'然后'但它为purpose_id抛出一个错误,说它未定义,它不明白为什么,我整天都遇到同样的问题,在某些时候我通过更改分号修复了其中一个,但我不知道它为什么有效...

我查了一个简单的查询

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)
    })

})

会返回结果

顺便说一下,我使用mongoose和bluebird作承诺

请帮忙! 谢谢

2 个答案:

答案 0 :(得分:0)

当你将回调函数传递给.exec时,它不再返回一个承诺(或任何事情)。这就是为什么purpose未定义的原因。

由于您已经使用了承诺,因此您可以链接.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();
}

答案 1 :(得分:0)

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,这样如果任何承诺被拒绝,它将被缓存在最后