2012-04-07 8 views
5

मेरे पास एक्सप्रेस के साथ नोडजेएस में लिखा गया है और एप्लिकेशन इवेंटइमीटर का उपयोग करने के लिए उत्सुक घटनाओं को सुनकर मुख्य कोड में प्लगइन के साथ प्लगइन आर्किटेक्चर बनाने के लिए एक प्रकार का प्लगइन आर्किटेक्चर बनाने का प्रयास कर रहा है।नोडजेएस इवेंट उत्सर्जित करने के लिए कॉलबैक के लिए प्रतीक्षा करें

मेरी समस्या तब होती है जब एक प्लगइन फ़ंक्शन एक एसिंक अनुरोध (इस मामले में मोंगो से डेटा प्राप्त करने के लिए) बनाता है, इससे प्लगइन कोड समाप्त हो जाता है और मूल एमिटर पर नियंत्रण वापस आ जाता है जो एसिंक अनुरोध से पहले निष्पादन को पूरा करेगा प्लगइन कोड खत्म होता है।

उदाहरण के लिए:

मुख्य अनुप्रयोग:

// We want to modify the request object in the plugin 
self.emit('plugin-listener', request); 

प्लगइन:

// Plugin function listening to 'plugin-listener', 'request' is an arg 
console.log(request); 

// Call to DB (async) 
this.getFromMongo(some_data, function(response){ 
    // this may not get called until the plugin function has finished! 
} 

'getFromMongo' समारोह से मुख्य कोड के लिए वापस एक कॉलबैक फ़ंक्शन से बचने के लिए मेरे कारण है कि वहाँ घटना को सुनकर 0 या कई प्लगइन्स हो सकते हैं। आदर्श रूप में मैं डीबी सामान मुख्य अनुप्रयोग के लिए नियंत्रण लौटने

कई धन्यवाद

उत्तर

3

प्लगइन के लिए EventEmitter का उपयोग करने से पहले समाप्त होने की प्रतीक्षा करने के लिए कोई रास्ता चाहते हैं/मिडलवेयर प्रबंधन नहीं आदर्श है, क्योंकि आप सुनिश्चित नहीं कर सकते कि श्रोताओं हो रहा है अनुक्रमिक रूप से निष्पादित, अगर उनके पास असीमित कोड है। यह विशेष रूप से एक समस्या है जब ये श्रोताओं एक-दूसरे या एक ही डेटा के साथ बातचीत करते हैं।

यही कारण है कि मिडलवेयर फ़ंक्शंस को कनेक्ट/एक्सप्रेस एक सरणी में संग्रहीत किया जाता है और एक EventEmitter का उपयोग करने के बजाय एक के बाद निष्पादित किया जाता है; उन्हें प्रत्येक को अगली() कॉल करने की आवश्यकता होती है; जब वे अपना काम कर रहे होते हैं तो कार्य करें।

3

आप तुल्यकालिक व्यवहार के साथ एसिंक्रोनस कॉल मिश्रण नहीं कर सकते हैं। यदि आप ईवेंट एमिटर (जो क्लॉवाडीस के रूप में आपके लिए आदर्श नहीं हो सकता है) के साथ चिपकने जा रहे हैं, तो आपको अपनी प्लगइन को उस ईवेंट को उत्सर्जित करने की आवश्यकता होगी जो मुख्य ऐप में फ़ंक्शन को ट्रिगर करता है जिसमें वह कोड होता है जिसे आप चाहते हैं निष्पादित करने के लिए 'प्रतीक्षा करें'। आपको बदले में उन सभी प्लगइन कॉलों का ट्रैक रखना होगा जिन्हें आपने ईवेंट कॉल के लिए इंतजार कर रहे हैं ताकि आपका मुख्य कोड तब तक नहीं चल सके जब तक कि सभी प्लगइन कॉलों ने मोंगोडीबी कॉलबैक समाप्त नहीं किया हो।

var callList = ['pluginArgs1', 'pluginArgs2', 'pluginArgs3']; 
for (var i = 0; i < callList.length; i++){ 
    self.emit('plugin-listener', callList[i], i); 
} 

self.on('plugin-callback', function(i){ 
    callList.splice(i, 1); 
    if (callList.length < 1){ 
    //we're done, do something 
    } 
}); 
0

इसे अपने आप को आज़माया नहीं लेकिन आप कार्यों की एक सरणी कोड है कि घटना उत्सर्जित द्वारा निष्पादित करने के लिए के रूप में घटना के डेटा वस्तु में एक संपत्ति इस्तेमाल कर सकते हैं:

श्रोताओं

foo.on('your-event', function(data) { 
    console.log(data); 
    // Then add the asynchronous code to a callbacks array 
    // in the event data object 
    data.callbacks.push(function(next) { 
    getFromMongo(some_data, function(err, result) { next(err) } 
    } 
}); 

Emitter

self.emit('your-event', data); 
// listeners have modified data object, 
// some might have added callback to data.callbacks 
// (suppose you use async) 
async.series(data.callbacks); 
1

निर्णय उसी तरह की कुछ घटनाओं के बारे में बनाने के लिए था कि मुझे क्लाइंट को प्रतिक्रिया वापस करने से पहले कभी-कभी प्रतीक्षा करने की आवश्यकता होती है और कभी-कभी नहीं (जब HTTP अनुरोध संदर्भ में नहीं)।

मेरे लिए सबसे आसान तरीका घटना के अंतिम तर्क के रूप में कॉलबैक जोड़ना था।

Stuff.on('do_some_stuff', function(data, data2, callback) { 
    // stuff to do 
    // ... 
    if (typeof callback === "function") return callback(err, result); 
}); 

मैं जानता हूँ कि मिश्रण घटना और कॉलबैक गंदा हो सकता है कि लेकिन मैं क्या जरूरत के लिए है कि काम ठीक:

Stuff.emit('do_some_stuff', data, data2, callback); 

घटना की जांच में अगर वहाँ एक कॉलबैक है। मैं जो अन्य समाधान देखता हूं वह है जिसे @redben द्वारा प्रस्तावित किया गया है: ईवेंट के अंत में एक उत्सर्जन कार्य जोड़ें। समस्या तब होती है जब HTTP संदर्भ में आपको अनन्य कुंजी की आवश्यकता होती है, इसलिए यदि वे प्रति उपयोगकर्ता अलग-अलग सामान करते हैं तो आपकी घटनाएं गड़बड़ नहीं होती हैं।

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