2016-01-07 8 views
8

उदाहरण पर विचार करें: मेरे पास निम्नलिखित express.js ऐप है (नीचे कोड स्निपेट देखें)। मैं पूरे एप जीवनकाल के दौरान डीबी के साथ एक लगातार कनेक्शन रखना चाहता हूं, और अपनी सेवा के लिए एक लगातार कनेक्शन (जिसे एसिंक कॉल शुरू करने की आवश्यकता है)। और कुछ प्रविष्टि बिंदु हैं, यानी कोई भी मेरे प्रोटोकॉल के माध्यम से न केवल मेरे ऐप तक पहुंच सकता है। बेशक, मैं सेवा प्रारंभिक कोड डुप्लिकेशन से बचना चाहता हूं और ऐसी कई एसिंक-प्रारंभिक सेवाएं हो सकती हैं।express.js (या समान) ऐप्स के असीमित प्रारंभिक

/* app.js */ 
var app = require('express')(); 
// set views, use routes, etc. 
var db = require('monk/mongoose/etc')(...); // happily, usually it's a sync operation 
var myService = require('./myService');  // however, it's possible to have several such services 
myService.init(function(err, result) { 
    // only here an initialization process is finished! 
}); 

module.exports.app = app; 


/* http_server.js (www entry point) */ 
var app = require('app'); 
// create an HTTP server with this app and start listening 


/* telnet_server.js (other entry point) */ 
var app = require('app'); 
// create a Telnet server with this app and start listening 

ऊपर कोड स्निपेट में, समय http (या टेलनेट, या किसी अन्य) सर्वर शुरू कर रहा है द्वारा, वहाँ कोई गारंटी नहीं है, कि myService पहले से ही प्रारंभ हो जाता है।

तो, मुझे किसी भी तरह से अपने ऐप निर्माण कोड को पुनर्गठित करना होगा। अभी के लिए मैं अगले समाधान के साथ चिपके रहते हैं:

/* app.js */ 
var app = require('express')(); 
module.exports.app = app; 
module.exports.init = function(callback) { 
    var myService = require('./myService'); 
    myService.init(callback);  
} 

/* entry_point.js */ 
var app = require('app'); 
app.init(function(err) { 
    if (!err) { 
     // create an HTTP/Telnet/etc server and start listening 
    } 
}); 

तो, मेरे सवाल यह है: आम तरीका आवश्यक अतुल्यकालिक कॉल प्रारंभ करने सेवाओं प्रारंभ करने में क्या है?

+0

यह वास्तव में ऑपरेशन के किसी भी एसिंक सेट को क्रमबद्ध करने से अलग नहीं है। यदि आप उन्हें एक विशिष्ट क्रम में करना चाहते हैं, तो आप चेन वादे करते हैं या आप पहले एसिंक ऑपरेशन के समापन कॉलबैक में दूसरा ऑपरेशन करते हैं। यदि आपके पास एन स्वतंत्र एसिंक ऑपरेशंस हैं जो आपको कुछ और करने से पहले किया जाना चाहिए, तो वादे और 'Promise.all() 'का उपयोग करें। एक सर्वर बनाम एकाधिक एसिंक संचालन के किसी अन्य समन्वय को शुरू करने के लिए कोई अलग नहीं है। – jfriend00

उत्तर

0

मैंने कोड के नमूने के साथ gist here बनाया है जो मैं आमतौर पर इस कार्य के लिए उपयोग करता हूं। (यह क्यू वादा पुस्तकालय का उपयोग करता है, लेकिन आसानी से किसी भी अन्य वादों का उपयोग करने के लिए संशोधित किया जा सकता है lib)।

मूल विचार एप रीढ़ की हड्डी का वर्णन एसिंक्रोनस प्रारंभिक चरणों के अनुक्रम के रूप में करना है। प्रत्येक चरण एक या अधिक एसिंक कार्यों को कॉल करता है और परिणाम को किसी नाम से जोड़ता है; स्टार्टअप प्रक्रिया केवल अगले चरण के लिए सभी मानों को हल करने के बाद ही अगले प्रारंभिक चरण में प्रगति होती है, और उसके बाद के चरणों को पिछले चरणों द्वारा हल किए गए सभी मानों तक पहुंच सकते हैं। यह ऐप के भीतर सेवाओं और घटकों के निर्भरता क्रम को आसानी से वर्णित करने की अनुमति देता है।

उदाहरण के लिए, इस प्रकार एक रीढ़ परिभाषित किया जा सकता:

var app = [ 
    { s1: startService1 }, 
    { s2: startService2, s3: startService3 }, 
    { s4: startService4 } 
] 

(ध्यान दें कि प्रत्येक कदम परिभाषा, बस प्रत्येक समारोह दिया जाता है के संदर्भ; - सार में दिखाया गया है - start() समारोह प्रत्येक लागू करेगा सही क्रम में कार्य)।

function startService4(app) { 
    var s1 = app.s1; 
    var s2 = app.s2; 
    var deferred = Q.defer(); 
    // ... start the service, do async stuff ... 
    return deferred; 
} 

समारोह के एप्लिकेशन तर्क कॉन्फ़िगर किया गया एप्लिकेशन रीढ़ की हड्डी का प्रतिनिधित्व करता है, और से परिणाम:

startXxx वार्स में से प्रत्येक एक समारोह जो एक तर्क लेता जैसे है, और एक आस्थगित वादा देता है, पिछले प्रारंभिक चरण इसके नामित गुणों के रूप में उपलब्ध हैं।

मैंने इस पैटर्न का काफी जटिल सिस्टम में उपयोग किया है, और इसे सिस्टम की उच्च स्तरीय संरचना को परिभाषित करने के लिए एक सरल, लचीला और प्रभावी तरीका ढूंढता है।

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