2017-06-12 76 views
1

我有定义为参考其它documentObjectId阵列称为Storage一个documentUsersstorage属性。我试图让一个特定的用户,然后返回数组内的存储信息。猫鼬findOne内部环路

这是我的代码:

module.exports.storageDetail = function(req, res) { 
     User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
     var storageArray = []; 

     data.storages.forEach(function(record){ 
      Storage.findOne({_id: record}, function(err, storage){ 
      storageArray.push(storage); 
      }); 
     }); 

     return Promise.all(storageArray); 
     }).then(function(storageList){ 
     res.render('storage_template', { 
      storage: storageList 
     }); 
     console.log(storageList); 
     }); 
} 

但执行后,storageList是一个空数组。

我是node.js的新手,请让我知道是否需要提供更多信息。

回答

1

所以这里的重点是你需要.exec()才能返回Promise。这就是为什么你的尝试失败。但是,语法上也有更好的方法。

而是使用.map()并调用.exec()返回无极

User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
    var storageArray = data.storages.map(function(id) { 
    return Storage.findOne({_id: id }).exec() 
    }); 
    return Promise.all(storageArray); 
}).then(function(storageList){ 
    res.render('storage_template', { 
    storage: storageList 
    }); 
    console.log(storageList); 
}); 

或者改用$in.find()其中,该方法返回一个数组和运营商允许你指定一个事物的阵列,以匹配:

User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
    return Storage.find({ "_id": { "$in": data.storages } }).exec(); 
}).then(function(storageList){ 
    res.render('storage_template', { 
    storage: storageList 
    }); 
    console.log(storageList); 
}); 

它也基本上看起来像你可以简单地使用.populate()

User.findOne({'userId': req.user.userId}, 'storages') 
    .populate('storages') 
    .then(function(data) { 
    res.render('storage_template', { 
     storage: data.storages 
    }); 
    console.log(data.storages); 
    }); 

但是,在您的问题中,如果这些参数实际上定义为对Storage型号的参考,则不清楚。

另请参阅猫鼬文档。

+0

这两种解决方案是伟大的工作!你能不能告诉我如何使用ES5的第一个? – Valip

+0

@Valip我用普通函数替换了胖箭头语法。这里的要点是'.exec()'来获得Promise。 –

0

//如果你正在使用猫鼬那么你可以使用.populate()Storage集合让你storages信息的详情做NPM安装lodash

const _ = require('lodash'); 
module.exports.storageDetail = function(req, res) { 
    User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
    var storageArray = []; 
    let queries = _.map(data.storages, (record)=>{ 
    return Storage.findOne({_id: record}, function(err, storage){ 
     storageArray.push(storage); 
     }); 
}) 

    return Promise.all(queries); 
    }).then(function(storageList){ 
    res.render('storage_template', { 
     storage: storageList 
    }); 
    console.log(storageList); 
    }); 
} 
1

可以试试这个

module.exports.storageDetail = function(req, res) { 
    User.findOne({'userId': req.user.userId}, 'storages') 
    .populate('storages') 
    .exec(function (err, storageList) { 
     if (err) return handleError(err); 
     console.log(storageList); 
     res.render('storage_template', { 
     storage: storageList 
     }); 
    }); 
} 

使用此.populate()首先确保你的User模型,你添加ref申请storages

,如:

storages: [{ type: Schema.Types.ObjectId, ref: 'Storage' }]