2017-06-12 177 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' }]