TypeScript में Event-driven आर्किटेक्चर: जब कोड एक-दूसरे को "सुनता" है
\n\nकल्पना करें कि आप एक जटिल वेब एप्लिकेशन लिख रहे हैं: मैसेंजर, ट्रेडिंग बॉट या सर्वर मॉनिटरिंग सिस्टम। कुछ समय बाद आपको एहसास होता है: फंक्शन को चेन में कॉल करना एक बुरा सपना है। एक मॉड्यूल दूसरे को खींचता है, तीसरा चौथे पर निर्भर करता है, और लॉजिक बदलने पर सब कुछ ताश के पत्तों की तरह बिखर जाता है।
\n\nपरिचित लगता है? तो आपको चाहिए TypeScript में Event-driven आर्किटेक्चर। यह सिर्फ एक फैशनेबल शब्द नहीं है, बल्कि कोड को लचीला, विस्तार योग्य और समझने योग्य बनाने का एक वास्तविक तरीका है। इस लेख में, हम जानेंगे कि इवेंट-ड्रिवन प्रोग्रामिंग कैसे काम करती है, TypeScript में अपनी इवेंट बस लिखेंगे और देखेंगे कि यह वास्तव में कहाँ काम आती है।
\n\nEvent-driven आर्किटेक्चर सरल शब्दों में क्या है
\n\nEvent-driven आर्किटेक्चर (इवेंट-ओरिएंटेड आर्किटेक्चर) एक ऐसा दृष्टिकोण है जिसमें सिस्टम के घटक इवेंट के माध्यम से संवाद करते हैं। एक मॉड्यूल एक इवेंट जनरेट करता है (जैसे, "उपयोगकर्ता ने रजिस्टर किया"), और दूसरे उस पर सब्सक्राइब करके प्रतिक्रिया देते हैं। वे सीधे एक-दूसरे से जुड़े नहीं होते।
\n\nअमूर्त लगता है? आइए जीवन के एक उदाहरण से समझते हैं। एक ऑफिस की कल्पना करें:
\n- \n
- पारंपरिक तरीका: बॉस खुद हर कर्मचारी के पास जाकर कहता है: "रिपोर्ट बनाओ।" \n
- Event-driven: बॉस चिल्लाता है: "रिपोर्ट चाहिए!" — और जो भी इसे बना सकता है, वह खुद काम पर लग जाता है। \n
दूसरे मामले में, बॉस को यह जानने की ज़रूरत नहीं है कि रिपोर्ट कौन बनाएगा। वह सिर्फ इवेंट भेजता है। और कर्मचारी बॉस की लॉजिक को बदले बिना जुड़ और छूट सकते हैं। यही है इवेंट-ड्रिवन प्रोग्रामिंग का सार।
\n\nइवेंट आर्किटेक्चर के लिए TypeScript क्यों आदर्श है
\n\nJavaScript अपने आप में इवेंट-ड्रिवन है (addEventListener याद रखें), लेकिन बड़े प्रोजेक्ट्स में टाइप्स के बिना अराजकता शुरू हो जाती है। TypeScript इवेंट्स इस समस्या को हल करते हैं: आपको ठीक-ठीक पता होता है कि इवेंट में कौन सा डेटा आ रहा है, और कंपाइलर डेवलपमेंट के दौरान ही एरर पकड़ लेगा, रनटाइम पर नहीं।
इसके अलावा, TypeScript जेनेरिक्स, ओवरलोड्स और कॉलबैक की सख्त टाइपिंग को सपोर्ट करता है — वह सब कुछ जो एक मजबूत इवेंट बस बनाने के लिए चाहिए।
\n\nTypeScript में स्क्रैच से Event Bus लिखना
\n\nचलिए एक सरल लेकिन काम करने वाले उदाहरण से शुरू करते हैं। हम EventBus क्लास बनाएंगे — एक सेंट्रल इवेंट बस, जिसके माध्यम से सभी मॉड्यूल संवाद करेंगे।
// event-bus.ts\ntype EventHandler<T = any> = (data: T) => void;\n\nclass EventBus {\n private handlers: Map<string, EventHandler[]> = new Map();\n\n // इवेंट पर सब्सक्राइब करना\n on<T>(event: string, handler: EventHandler<T>): void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, []);\n }\n this.handlers.get(event)!.push(handler as EventHandler);\n }\n\n // इवेंट से अनसब्सक्राइब करना\n off(event: string, handler: EventHandler): void {\n const handlers = this.handlers.get(event);\n if (handlers) {\n this.handlers.set(event, handlers.filter(h => h !== handler));\n }\n }\n\n // इवेंट को एमिट करना\n emit<T>(event: string, data: T): void {\n const handlers = this.handlers.get(event);\n if (handlers) {\n handlers.forEach(handler => handler(data));\n }\n }\n}\n\nexport const globalEventBus = new EventBus();\n\nहमने बस इतना करके TypeScript में एक सरल event-driven आर्किटेक्चर लिख दिया है। अब कोई भी मॉड्यूल globalEventBus को इम्पोर्ट कर सकता है और या तो इवेंट सुन सकता है या उन्हें जनरेट कर सकता है।
उपयोग का उदाहरण: नोटिफिकेशन और लॉगिंग
\n\nमान लीजिए हमारे पास एक ऑथेंटिकेशन मॉड्यूल और एक नोटिफिकेशन मॉड्यूल है। उन्हें एक-दूसरे के बारे में सीधे जानने की ज़रूरत नहीं है।
\n\n// auth-module.ts\nimport { globalEventBus } from './event-bus';\n\nexport function loginUser(email: string): void {\n // ... लॉगिन की लॉजिक\n console.log(`उपयोगकर्ता ${email} लॉगिन हुआ`);\n globalEventBus.emit('user:loggedIn', { email });\n}\n\n// notification-module.ts\nimport { globalEventBus } from './event-bus';\n\nglobalEventBus.on('user:loggedIn', (data: { email: string }) => {\n console.log(`स्वागत है, ${data.email}! नोटिफिकेशन भेजा जा रहा है...`);\n // नोटिफिकेशन भेजने की लॉजिक\n});\n\nअब auth-module को यह जानने की ज़रूरत नहीं है कि नोटिफिकेशन कौन भेज रहा है। वह सिर्फ एक इवेंट एमिट करता है, और notification-module उसे सुनता है। यह कोड को साफ, अलग और आसानी से टेस्ट करने योग्य बनाता है।
Event-driven आर्किटेक्चर के फायदे
\n\n- \n
- लूज़ कपलिंग: मॉड्यूल एक-दूसरे पर निर्भर नहीं होते। \n
- स्केलेबिलिटी: नए फीचर जोड़ना आसान है — बस एक नया इवेंट हैंडलर जोड़ें। \n
- टेस्टेबिलिटी: हर मॉड्यूल को अलग-अलग टेस्ट किया जा सकता है। \n
- मेंटेनबिलिटी: कोड साफ और समझने में आसान रहता है। \n
अब आपके पास TypeScript में Event-driven आर्किटेक्चर की ठोस समझ है। इसे अपने प्रोजेक्ट में आज़माएं और देखें कि यह कितना लचीलापन लाता है!