2017-06-15 62 views
1

我試圖生成一個文件與node.js需要運行多個不相關的數據庫查詢從mongo數據庫。查詢Mongoose多次沒有嵌套

這裏是我當前的代碼:

Data.find({}, function(err, results) { 
    if (err) return next(err); 
    //finished getting data 
    res.render('page'); 
    } 
} 

的問題是,如果我嘗試運行另一個查詢,我似乎已經到第一個中嵌套它,使它等待第一個前完成開始,然後我必須將res.render()放在最內層的嵌套查詢中(如果我不這樣做,res.render()將在數據庫完成抓取數據之前調用,並且不會使用頁面呈現) 。

我要做的:

Data.find({}, function(err, results) { 
    if (err) return next(err); 
    //finished getting data 

    Data2.find({}, function(err, results2) { 
     if (err) return next(err); 
     //finished getting data 2 
     res.render('page'); 
     } 
    } 
    } 
} 

我將有超過2個查詢,所以如果我繼續築巢他們它會帶來麻煩的真快。是否有一種更簡潔的方法來實現這一點,比如讓代碼等待,直到返回所有數據並繼續運行該函數之前運行該函數?

+0

什麼是用例?你想**所有**結果來自兩個查詢還是數據「相關」以某種方式?兩種情況都有不同的答案。它也似乎是你實際上使用[mongoose](http://mongoosejs.com/docs/guide.html),但如果你確認的話,它會很好。 –

+0

是的,我正在使用貓鼬。數據不相關,我試圖創建一個站點地圖,有些我只是爲各種數據集生成一個URL列表。 – stackers

+0

提供的答案中是否有某些東西可以解決您的問題?如果是這樣,請評論答案以澄清究竟需要解決的問題。如果它確實回答了你問的問題,那麼請注意[接受你的答案](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)給你的問題問。 –

回答

1

對於貓鼬,您可能只需在每個查詢的結果數組上執行Promise.all()並使用.concat()即可。

作爲一個完整的演示:

var async = require('async'), 
    mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var d1Schema = new Schema({ "name": String }); 
var Data1 = mongoose.model("Data1", d1Schema); 

var d2Schema = new Schema({ "title": String }); 
var Data2 = mongoose.model("Data2", d2Schema); 

mongoose.set('debug',true); 
mongoose.connect('mongodb://localhost/test'); 

async.series(
    [ 
    // Clean 
    function(callback) { 
     async.each([Data1,Data2],function(model,callback) { 
     model.remove({},callback) 
     },callback); 
    }, 
    // Setup some data 
    function(callback) { 
     async.each([ 
     { "name": "Bill", "model": "Data1" }, 
     { "title": "Something", "model": "Data2" } 
     ],function(data,callback) { 
     var model = data.model; 
     delete data.model; 
     mongoose.model(model).create(data,callback); 
     },callback); 
    }, 
    // Actual Promise.all demo 
    function(callback) { 
     Promise.all([ 
     Data1.find().exec(), 
     Data2.find().exec() 
     ]).then(function(result) { 
     console.log([].concat.apply([],result)); 
     callback() 
     }).catch(callback); 
    } 
    ], 
    function(err) { 
    if (err) throw err; 
    mongoose.disconnect(); 
    } 
) 

我只是在那裏async混合例如簡潔,但它的肉是:

Promise.all([ 
    Data1.find().exec(), 
    Data2.find().exec() 
    ]).then(function(result) { 
    console.log([].concat.apply([],result)); 
    }) 

Promise.all()基本上等待並結合了這兩個結果,這將是一個「陣列數組」,但.concat()負責。其結果將是:

[ 
    { _id: 59420fd33d48fa0a490247c8, name: 'Bill', __v: 0 }, 
    { _id: 59420fd43d48fa0a490247c9, title: 'Something', __v: 0 } 
] 

顯示的是從每個集合中的對象,在一個陣列接合在一起。

您也可以使用async.concat方法作爲替代方法,但除非您已經使用該庫,否則可能只是堅持承諾。

+0

所以承諾基本上只是一個JavaScript函數,等待一個或多個其他函數完成,然後運行一個函數,一旦他們都完成了? – stackers

+0

@stackers這可能是通過閱讀可用材料的最佳答案。以下是[Promise]的MDN定義(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise)。但或多或少,你的定義是基本的總結。 'Promise.all'也如答案中的鏈接所描述的那樣具體等待** all ** Promise對象傳遞給它以解析並返回數組中的組合結果。我們''。concat()'到一個數組,就像答案所說的那樣。實質上,我們將所有「回調」合併爲一個。 –