2013-08-02 19 views
32

मैं जेड टेम्पलेट प्रस्तुत करने से पहले कई मोंगोडीबी प्रश्नों को बनाने की कोशिश कर रहा हूं, लेकिन मुझे यह पता नहीं चल सकता कि टेम्पलेट को प्रस्तुत करने से पहले सभी मोंगो क्वेरीज पूर्ण होने तक कैसे प्रतीक्षा करें ।Node.js - एकाधिक एसिंक कॉल के लिए प्रतीक्षा करें

exports.init = function(req, res){ 


     var NYLakes = {}; 
     var NJLakes = {}; 
     var filterNY = {"State" : "NY"}; 
     db.collection('lakes').find(filterNY).toArray(function(err, result) { 
      if (err) throw err; 
      NYLakes = result; 
     }); 

     var filterNJ = {"State" : "NJ"}; 
     db.collection('lakes').find(filterNJ).toArray(function(err, result) { 
      if (err) throw err; 
      NJLakes = result; 
     }); 

     res.render('explore/index', 
      { 
       NYlakes: NYLakes, 
       NJlakes: NJLakes 
      } 
     ); 

    }; 

उत्तर

17

मान लिया जाये कि आप बल्कि इंतजार कर एक को समाप्त करने के लिए अगले शुरू करने से पहले, आप कितने आपरेशन प्रत्येक कॉलबैक में पूरा कर लिया है को ट्रैक करना होगा की तुलना में समानांतर में दो आपरेशन चलाना चाहते हैं।

कच्चे Node.js जावास्क्रिप्ट में, एक तरीका यह है इस होगा:

exports.init = function(req, res){ 
    var NYLakes = null; 
    var NJLakes = null; 
    var filterNY = {"State" : "NY"}; 

    db.collection('lakes').find(filterNY).toArray(function(err, result) { 
     if (err) throw err; 
     NYLakes = result; 
     complete(); 
    }); 

    var filterNJ = {"State" : "NJ"}; 
    db.collection('lakes').find(filterNJ).toArray(function(err, result) { 
     if (err) throw err; 
     NJLakes = result; 
     complete(); 
    }); 

    function complete() { 
     if (NYLakes !== null && NJLakes !== null) { 
      res.render('explore/index', { 
       NYlakes: NYLakes, 
       NJlakes: NJLakes 
      }); 
     } 
    } 

}; 

असल में यहाँ क्या हो रहा है कि आप प्रत्येक आपरेशन के अंत की जाँच करता है, तो उन सभी को समाप्त कर दिया है, और कम से है उस बिंदु पर आप ऑपरेशन खत्म कर देते हैं।

यदि आप इनमें से बहुत कुछ कर रहे हैं, तो इस तरह की चीज़ों को प्रबंधित करना आसान बनाने के लिए async लाइब्रेरी को एक टूल के उदाहरण के रूप में देखें।

+0

बहुत साफ। अच्छा लगा। –

+0

इसमें दौड़ की स्थिति होगी। यदि दोनों एसिंक ऑपरेशन पूर्ण() को कॉल करने से ठीक पहले तक निष्पादित करते हैं, तो वे दोनों पूर्ण कथन के शरीर को पूर्ण() में निष्पादित करने के लिए आवश्यक शर्त के साथ कॉल कर सकते हैं। असंभव, लेकिन संभव है। –

+0

@ ghert85 एक बहुप्रचारित वातावरण में आप सही होंगे, लेकिन node.js एकल थ्रेडेड है। इसलिए कोड लूप पर लौटने के बाद कोड को बाधित नहीं किया जा सकता है और यह दौड़ स्थिति नहीं हो सकती है। –

5

आप async मॉड्यूल का उपयोग कर सकते हैं:

var states = [{"State" : "NY"},{"State" : "NJ"}]; 

var findLakes = function(state,callback){ 
    db.collection('lakes').find(state).toArray(callback); 
} 

async.map(states, findLakes , function(err, results){ 
    // do something with array of results 
}); 
52

मैं अंडरस्कोर/lodash के एक बड़े प्रशंसक हूँ, इसलिए मैं आमतौर पर _.after है, जो एक समारोह है कि केवल समय की एक निश्चित संख्या में बुलाया जा रहा है के बाद निष्पादित करता है बनाता है का उपयोग करें।

var finished = _.after(2, doRender); 

asyncMethod1(data, function(err){ 
    //... 
    finished(); 
}); 

asyncMethod2(data, function(err){ 
    //... 
    finished(); 
}) 

function doRender(){ 
    res.render(); // etc 
} 

जावास्क्रिप्ट के बाद से function funcName() वाक्य रचना के साथ परिभाषित कार्यों की परिभाषा फहराते हैं, अपने कोड स्वाभाविक रूप से पढ़ता है: शीर्ष से नीचे।

+0

उत्कृष्ट, धन्यवाद :) – iConnor

1

Wait.for https://github.com/luciotato/waitfor

Wait.for का उपयोग कर:

exports.init = function(req, res){ 

    var NYLakes = {}; 
    var NJLakes = {}; 

    var coll = db.collection('lakes'); 

    var filterNY = {"State" : "NY"}; 
    var a = wait.forMethod(coll,'find',filterNY); 
    NYLakes = wait.forMethod(a,'toArray'); 

    var filterNJ = {"State" : "NJ"}; 
    var b = wait.forMethod(coll,'find',filterNJ); 
    NJLakes = wait.forMethod(b,'toArray'); 

    res.render('explore/index', 
     { 
      NYlakes: NYLakes, 
      NJlakes: NJLakes 
     } 
    ); 

}; 

समानांतर नक्शा wait.for का उपयोग कर समानांतर में अनुरोध:

exports.init = function(req, res){ 

    var coll = db.collection('lakes'); 

    //execute in parallel, wait for results 
    var result = wait.parallel.map(
        [{coll:coll,filter:{"State" : "NY"}} 
        , {coll:coll,filter:{"State" : "NJ"}}] 
        , getData); 

    res.render('explore/index', 
     { 
      NYlakes: result[0], 
      NJlakes: result[1] 
     } 
    ); 

}; 

//map function 
function getData(item,callback){ 
try{ 
    var a = wait.forMethod(item.coll,'find',item.filter); 
    var b = wait.forMethod(a,'toArray'); 
    callback (null, b); 
} catch(err){ 
    callback(err); 
} 

मैं परिचित नहीं हूँ मोंगो के साथ, तो आपको कॉल समायोजित करना पड़ सकता है।

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