TypeScript में कॉन्करेंसी: थ्रेड्स, गोरूटीन्स और async/await — प्रैक्टिकल गाइड

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

TypeScript में कॉन्करेंसी: Event Loop से Web Workers तक

\n\n

क्या आपने कभी देखा है कि आपका ब्राउज़र या Node.js ऐप किसी भारी गणना या बड़े JSON को प्रोसेस करते समय "फ्रीज़" हो जाता है? वो जाना-पहचाना असहायता का एहसास, जब इंटरफ़ेस क्लिक पर रिस्पॉन्ड नहीं करता, और सर्वर नए रिक्वेस्ट को इग्नोर करता है। इसकी वजह यह है कि JavaScript (और इसका सख्त भाई TypeScript) डिफ़ॉल्ट रूप से एक सिंगल-थ्रेडेड भाषा है। लेकिन इसका मतलब यह नहीं कि हम धीमे प्रोग्राम के लिए अभिशप्त हैं। इसके विपरीत, TypeScript में कॉन्करेंसी का सही उपयोग करके हम तेज़ और रिस्पॉन्सिव ऐप्लिकेशन बना सकते हैं।

\n\n

इस आर्टिकल में हम सिर्फ़ टर्म्स की लिस्ट नहीं देंगे। हम समझेंगे कि async/await असल में कैसे काम करता है, Event Loop के अंदर क्या चल रहा है, क्या TypeScript में Go जैसी "गोरूटीन्स" का उपयोग संभव है, और कब हमें Web Workers के ज़रिए असली थ्रेड्स का इस्तेमाल करना चाहिए। चलिए शुरू करते हैं!

\n\n

1. एसिंक्रोनस बनाम पैरेललिज़्म: क्या अंतर है?

\n\n

कोड में गहराई से जाने से पहले, आइए शब्दों पर सहमत हो जाएं। बहुत से लोग इन दोनों कॉन्सेप्ट को गलत समझते हैं, जो गलत है।

\n\n
    \n
  • एसिंक्रोनस (कॉन्करेंसी) — यह प्रोग्राम की वह क्षमता है जिसमें वह एक कार्य शुरू करता है, दूसरे कार्य पर स्विच करता है जब पहला इंतज़ार कर रहा हो (जैसे, सर्वर से रिस्पॉन्स), और बाद में वापस आता है। एक समय में केवल एक इंस्ट्रक्शन एक्ज़ीक्यूट होती है।
  • \n
  • पैरेललिज़्म — यह दो या अधिक कार्यों को प्रोसेसर के अलग-अलग कोर पर एक ही समय में एक्ज़ीक्यूट करना है।
  • \n
\n\n

TypeScript बॉक्स से बाहर ही एसिंक्रोनसिटी देता है। पैरेललिज़्म के लिए अलग-अलग थ्रेड्स बनाने की ज़रूरत होती है — ब्राउज़र में इसे Web Workers कहते हैं, और Node.js में worker_threads। इस अंतर को याद रखें, नहीं तो आप ऐसा कोड लिख सकते हैं जो मेन थ्रेड को ब्लॉक करने के कारण "लैग" करेगा।

\n\n

2. Event Loop और कॉलबैक — TypeScript कॉन्करेंसी की नींव

\n\n

JavaScript/TypeScript में एसिंक्रोनसिटी का मुख्य रहस्य Event Loop (इवेंट लूप) है। इसे कार्यों की एक कतार समझें। मेन थ्रेड एक कार्य लेता है, उसे एक्ज़ीक्यूट करता है — अगर वह सिंक्रोनस है, तो तुरंत रिज़ल्ट देता है। अगर यह कोई एसिंक्रोनस ऑपरेशन है (जैसे, setTimeout या fetch), तो उसे "अलग" भेज दिया जाता है (Web API या libuv में), और मेन थ्रेड अगला कोड एक्ज़ीक्यूट करना जारी रखता है।

\n\n

जब एसिंक्रोनस ऑपरेशन पूरा हो जाता है, तो उसका कॉलबैक कतार (Task Queue या Microtask Queue) में आ जाता है। Event Loop लगातार जाँचता है कि कॉल स्टैक खाली है या नहीं, और अगर खाली है — तो कतार से पहला कार्य लेकर एक्ज़ीक्यूट करता है।

\n\n
// एक सरल उदाहरण जो इसे दर्शाता है\nconsole.log('1. शुरुआत');\n\nsetTimeout(() => {\n    console.log('3. टाइमर चालू हुआ');\n}, 0);\n\nPromise.resolve().then(() => {\n    console.log('2. माइक्रोटास्क पूरा हुआ');\n});\n\nconsole.log('4. अंत');\n\n// आउटपुट: 1, 4, 2, 3
\n\n

ध्यान दें: Promise (माइक्रोटास्क) setTimeout (मैक्रोटास्क) से पहले एक्ज़ीक्यूट हुआ, भले ही टाइमर की देरी 0 ms थी। TypeScript ऑप्टिमाइज़ेशन के लिए यह जानना बहुत ज़रूरी है।

\n\n

3. Async/Await — वह शॉर्टकट जो सब कुछ बदल देता है

\n\n

ES2017 के आने के बाद से JS की दुनिया "पहले" और "बाद" में बंट गई। Async/await प्रॉमिसेस पर एक सिंटैक्टिक शुगर है, जो एसिंक्रोनस कोड को सिंक्रोनस जैसा बनाता है। यह कोई नए थ्रेड्स नहीं जोड़ता, लेकिन पढ़ने में आसानी को बहुत बढ़ा देता है।

\n\n
// एक फंक्शन जो देरी को सिम्युलेट करता है\nfunction delay(ms: number): Promise<void> {\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// async/await का उपयोग करते हुए एक एसिंक्रोनस फंक्शन\nasync function fetchUserData(userId: number): Promise<string> {\n    console.log(`उपयोगकर्ता ${userId} का डेटा माँग रहा हूँ...`);\n    await delay(2000); // नेटवर्क रिक्वेस्ट का अनुकरण\n    return `उपयोगकर्ता ${userId} का डेटा`;\n}\n\nasync function main() {\n    console.log('शुरुआत');\n    const user1 = await fetchUserData(1);\n    console.log(                

ब्लॉग

पुस्तक अनुशंसाएँ