2011-05-30 16 views
53

मैंगोज़ परिणामों के साथ एक पृष्ठ को प्रस्तुत करने के लिए जो कुछ भी मिल सकता है, वह ऐसा करने के लिए कहता है:खोज विधि से Mongoose परिणाम कैसे वापस करें?

users.find({}, function(err, docs){ 
    res.render('profile/profile', { 
     users:  docs 
    }); 
}); 

मैं क्वेरी से परिणाम कैसे वापस कर सकता हूं, इस तरह से?

var a_users = users.find({}); //non-working example 

ताकि मैं पेज पर प्रकाशित करने के लिए कई परिणाम प्राप्त कर सकूं?

जैसे:

/* non working example */ 
var a_users = users.find({}); 
var a_articles = articles.find({}); 

res.render('profile/profile', { 
     users: a_users 
    , articles: a_articles 
}); 

क्या यह किया जा सकता है?

+1

आपका सपना सच होगा जब [ES7 घूमता है] (http://jakearchibald.com/2014/es7-async-functions/)। – royhowie

+1

आपको [deasync] (https://www.npmjs.com/package/deasync) देखना चाहिए, इसलिए फ़ंक्शंस दिखते हैं कि उन्हें सिंक्रनाइज़ तरीके से निष्पादित किया गया है। इस समस्या की बेहतर समझ के लिए –

+0

और इसके समाधान का संदर्भ https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – devprashant

उत्तर

66

आप एक तुल्यकालिक प्रतिमान को मजबूर करने की कोशिश कर रहे हैं। बस काम नहीं करता है। node.js एकल धागा है, अधिकांश भाग के लिए - जब io किया जाता है, निष्पादन संदर्भ उत्पन्न होता है। सिग्नलिंग को कॉलबैक के साथ प्रबंधित किया जाता है। इसका मतलब यह है कि आप या तो चीजों को अच्छी तरह से दिखने के लिए नेस्टेड कॉलबैक, नामित फ़ंक्शंस, या फ्लो कंट्रोल लाइब्रेरी है।

https://github.com/caolan/async#parallel

async.parallel([ 
    function(cb){ 
     users.find({}, cb); 
    }, 
    function(cb){ 
     articles.find({}, cb); 
    } 
], function(results){ 
    // results contains both users and articles 
}); 
+0

@josh दूसरे में पहले फ़ंक्शन के परिणामों तक पहुंचने का कोई तरीका है? या वे केवल कॉलबैक में उपलब्ध हैं? – pkyeck

+4

@pkyeck यदि आप झरना या अन्य तरीकों में से एक का उपयोग कर सकते हैं जो चीजों को क्रमशः करते हैं। इस उदाहरण में, इन दोनों विधियों को process.nextTick का उपयोग करके समानांतर में चलाने की अनुमति है, जिसका अर्थ है कि फ़ंक्शन 1 के परिणाम फ़ंक्शन 2 – Josh

+0

पर उपलब्ध नहीं हैं Async NPM बहुत शक्तिशाली प्रतीत होता है, कभी-कभी हमें कुछ तुल्यकालिक कार्यों की आवश्यकता होती है। – Ito

16

आसान तरीका:

var userModel = mongoose.model('users'); 
var articleModel = mongoose.model('articles'); 
userModel.find({}, function (err, db_users) { 
    if(err) {/*error!!!*/} 
    articleModel.find({}, function (err, db_articles) { 
    if(err) {/*error!!!*/} 
    res.render('profile/profile', { 
     users: db_users, 
     articles: db_articles 
    }); 
    }); 
}); 

व्यावहारिक रूप से हर समारोह Node.js. में अतुल्यकालिक है तो मोंगोस का पता है। और यदि आप इसे क्रमशः कॉल करना चाहते हैं तो आपको Slide लाइब्रेरी जैसे कुछ का उपयोग करना चाहिए।

लेकिन आपके मामले में मुझे लगता है कि सबसे आसान तरीका कॉलबैक घोंसला करना है (यह पहले से उपयोगकर्ताओं के लिए f.e. quering लेखों की अनुमति देता है) या इसे एसिंक पुस्तकालयों की सहायता से पूरी तरह से समानांतर करें (Flow control/Async goodies देखें)।

+0

मुझे पता चला कि मैं कर सकता था इस तरह, हालांकि, मेरी बड़ी अंडरलेइंग समस्या को ठीक नहीं किया। मेरा उदाहरण शायद सबसे अच्छा नहीं था। मैं चीजों को एसिंक रखने में समझता हूं, लेकिन बड़ी समस्या यह है कि मैं कोड को एक ट्रूअर एमवीसी फैशन में व्यवस्थित रखने की कोशिश कर रहा हूं और ऐसा करने में मुश्किल हो रही है। मुझे इस विचार से नफरत है कि प्रत्येक पृष्ठ के नियंत्रक में मुझे इन सभी प्रश्नों को बनाना होगा - कि मेरे दिमाग में मॉडल में संभाला जाना चाहिए। तो मैं मॉडल को एक ही स्थान पर रखने और जानकारी का अनुरोध करने और इसे नियंत्रक को लौटने का एक तरीका जानने का प्रयास कर रहा हूं। – MrBojangles

+0

@ user776796 मेरी प्रोजेक्ट में मैंने मॉडलों को अलग-अलग फाइलों में रखा जो नियंत्रकों से पहले लोड हो रहे हैं। मोंगोस के मॉडल मेरे मॉडल के अंदर हैं और मैंने अक्सर उपयोग किए जाने वाले प्रश्नों के लिए शॉर्टकट फ़ंक्शन जोड़े। –

+0

ऐसा लगता है कि मेरे पास चीजें कैसे सेट हैं। शॉर्टकट फ़ंक्शंस से आप क्वेरी परिणाम कैसे लौट रहे हैं? – MrBojangles

1

मैं एक समारोह है कि मैं नोड कार्यों के लिए एक वापसी के रूप में काफ़ी उपयोग किया है।

function freturn (value, callback){ 
    if(callback){ 
     return callback(value); 
    } 
    return value; 
}; 

तब मेरे पास सभी हस्ताक्षरों में एक वैकल्पिक कॉलबैक पैरामीटर है।

1

मैं एक बहुत ही समान चीज़ से निपट रहा था लेकिन क्लाइंट से सॉकेट.ओ और डीबी एक्सेस का उपयोग कर रहा था। डाटाबेस को डेटा प्राप्त करने का मौका मिलने से पहले मेरा पता क्लाइंट को मेरी डीबी की सामग्री को फेंक रहा था ... इसलिए इसके लायक होने के लिए मैं अपने निष्कर्ष यहां साझा करूंगा:

डीबी को पुनः प्राप्त करने के लिए मेरा कार्य:

// पढ़ें बोर्डों - पूरा डीबी

var readBoards = function() { 
     var callback = function() { 
      return function(error, data) { 
       if(error) { 
        console.log("Error: " + error); 
       } 
       console.log("Boards from Server (fct): " + data); 

      } 
     }; 

     return boards.find({}, callback()); 
    }; 

मेरे सॉकेट घटना श्रोता:

socket.on('getBoards', function() { 
     var query = dbConnection.readBoards(); 
     var promise = query.exec(); 
     promise.addBack(function (err, boards) { 
      if(err) 
       console.log("Error: " + err); 
      socket.emit('onGetBoards', boards); 
     }); 
    }); 

तो समस्या हम वादा है कि नेवला हमें देता है का उपयोग हल करने के लिए और फिर एक बार हम डीबी मेरी सॉकेट इसे वापस ग्राहक के लिए उत्सर्जन करता है ...

क्या इसके लायक के लिए ...

20

मैं नेक्रोमन्ट यहाँ खेलने देंगे, के रूप में मैं अभी भी एक और देखने से डेटा प्राप्त हुआ है इसे करने का बेहतर तरीका।

अद्भुत वादा पुस्तकालय Bluebird और उसके promisifyAll() पद्धति का उपयोग करना:

Promise.promisifyAll(mongoose); 

सभी नेवला बनाता है (और इसके मॉडल) के साथ वादे लौटने कार्यों के रूप में उपलब्ध तरीकों,:

var Promise = require('bluebird'); 
var mongoose = require('mongoose'); 

Promise.promisifyAll(mongoose); // key part - promisification 

var users, articles; // load mongoose models "users" and "articles" here 

Promise.props({ 
    users: users.find().execAsync(), 
    articles: articles.find().execAsync() 
    }) 
    .then(function(results) { 
    res.render('profile/profile', results); 
    }) 
    .catch(function(err) { 
    res.send(500); // oops - we're even handling errors! 
    }); 

कुंजी भागों इस प्रकार हैं Async प्रत्यय (.exec().execAsync() बन जाता है, और इसी तरह)। .promisifyAll() विधि नोड.जेएस दुनिया में लगभग सार्वभौमिक है - आप इसका अंतिम तर्क के रूप में कॉलबैक में लेने वाले असीमित कार्यों को प्रदान करने वाले किसी भी चीज़ पर इसका उपयोग कर सकते हैं।

Promise.props({ 
    users: users.find().execAsync(), 
    articles: articles.find().execAsync() 
    }) 

.props() Bluebird विधि उसके गुण के रूप में किए गए वादे के वस्तु में लेता है, और सामूहिक वादा है कि हल हो गई हो जाता है जब दोनों डेटाबेस प्रश्नों (यहाँ - वादों) देता है उनके परिणाम वापस। (उह डी) लेख नेवला द्वारा डेटाबेस में पाया

के रूप में -

  • results.users - उन नेवला द्वारा डेटाबेस में पाया
  • results.articles: हल मूल्य अंतिम समारोह में हमारे results वस्तु है आप देख सकते हैं, हम इंडेंटेशन कॉलबैक नरक के पास भी नहीं पहुंच रहे हैं। दोनों डेटाबेस क्वेरी समानांतर में निष्पादित की जाती हैं - उनमें से किसी एक के लिए प्रतीक्षा करने की आवश्यकता नहीं होती है। संहिता संक्षिप्त और पठनीय है - प्रश्न में पोस्ट किए गए "गैर-कामकाजी उदाहरण" के लिए व्यावहारिक रूप से लंबाई और जटिलता (या इसकी कमी) में व्यावहारिक रूप से संबंधित है।

    वादे शांत हैं। उन्हें इस्तेमाल करें।

संबंधित मुद्दे