TypeScript में समवर्तीता और मल्टीथ्रेडिंग: A से Z तक
\nआधुनिक वेब डेवलपमेंट की दुनिया में, एप्लिकेशन का प्रदर्शन सबसे महत्वपूर्ण हो गया है। TypeScript, JavaScript पर एक सख्ती से टाइप की गई परत होने के नाते, डेवलपर्स को एसिंक्रोनसी और मल्टीथ्रेडिंग के साथ काम करने के लिए शक्तिशाली उपकरण प्रदान करता है। इस लेख में, हम समवर्तीता की मूलभूत अवधारणाओं को समझेंगे, जानेंगे कि Event Loop कैसे काम करता है, और Node.js में वास्तविक मल्टीथ्रेडिंग के लिए Worker Threads का उपयोग करना सीखेंगे।
\n\n1. एसिंक्रोनसी और Event Loop: TypeScript में समवर्तीता का आधार
\nमल्टीथ्रेडिंग के बारे में बात करने से पहले, यह समझना महत्वपूर्ण है कि TypeScript (और JavaScript) समवर्ती कार्यों को कैसे संभालता है। इसके मूल में Event Loop है - एक तंत्र जो नए थ्रेड बनाए बिना नॉन-ब्लॉकिंग इनपुट-आउटपुट ऑपरेशन को निष्पादित करने की अनुमति देता है।
\nएसिंक्रोनस कोड का एक सरल उदाहरण देखें:
\nasync function fetchData(url: string): Promise<string> {\n const response = await fetch(url);\n return response.text();\n}\n\nasync function main(): Promise<void> {\n console.log('लोडिंग शुरू');\n const data = await fetchData('https://api.example.com/data');\n console.log('डेटा प्राप्त हुआ:', data);\n}\n\nmain();\nconsole.log('कोड निष्पादित होता रहता है');\nइस उदाहरण में, await मुख्य थ्रेड को ब्लॉक नहीं करता है। जब तक सर्वर से प्रतिक्रिया की प्रतीक्षा की जाती है, Event Loop अन्य कार्यों को संसाधित करता रहता है, जैसे console.log का निष्पादन। इसे ही समवर्तीता कहते हैं - एक समय अवधि में कई कार्यों को संभालने की क्षमता, उनके बीच स्विच करके।
2. प्रॉमिस और async/await: एसिंक्रोनस ऑपरेशन का प्रबंधन
\nTypeScript एसिंक्रोनसी के साथ काम करने के लिए सुविधाजनक सिंटैक्स संरचनाएं प्रदान करता है। प्रॉमिस (Promises) ऐसी वस्तुएं हैं जो किसी एसिंक्रोनस ऑपरेशन के भविष्य के परिणाम का प्रतिनिधित्व करती हैं। async/await का संयोजन कोड को रैखिक और पढ़ने योग्य बनाता है।
एक अधिक जटिल परिदृश्य देखें - कई अनुरोधों का समानांतर निष्पादन:
\nasync function loadMultipleUsers(userIds: number[]): Promise<User[]> {\n const promises = userIds.map(id => fetch(`/users/${id}`).then(res => res.json()));\n return Promise.all(promises);\n}\n\n// उपयोग\nconst users = await loadMultipleUsers([1, 2, 3, 4, 5]);\nconsole.log(users); // सभी उपयोगकर्ता समानांतर रूप से लोड हुए\nPromise.all विधि सभी प्रॉमिस को एक साथ शुरू करती है, जो अनुक्रमिक लोडिंग की तुलना में निष्पादन को काफी तेज करती है। यह समवर्तीता का एक आदर्श उदाहरण है: कार्य एक ही थ्रेड के भीतर 'एक साथ' निष्पादित होते हैं।
3. वास्तविक मल्टीथ्रेडिंग: Node.js में Worker Threads
\nहालांकि एसिंक्रोनसी इनपुट-आउटपुट ऑपरेशन के लिए बहुत अच्छा काम करती है, यह CPU-इंटेंसिव कार्यों (इमेज प्रोसेसिंग, जटिल गणना, एन्क्रिप्शन) में मदद नहीं करती है। ऐसे मामलों के लिए, Node.js में Worker Threads मौजूद हैं - ऑपरेटिंग सिस्टम के वास्तविक थ्रेड।
\nएक अलग थ्रेड में फैक्टोरियल की गणना का उदाहरण देखें:
\n// worker.ts\nimport { parentPort } from 'worker_threads';\n\nfunction factorial(n: number): number {\n if (n === 0) return 1;\n return n * factorial(n - 1);\n}\n\nparentPort?.on('message', (n: number) => {\n const result = factorial(n);\n parentPort?.postMessage(result);\n});\n\n// main.ts\nimport { Worker } from 'worker_threads';\n\nfunction runWorker(n: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const worker = new Worker('./worker.ts');\n worker.postMessage(n);\n worker.on('message', resolve);\n worker.on('error', reject);\n });\n}\n\nasync function main() {\n const result = await runWorker(20);\n console.log('20 का फैक्टोरियल:', result);\n}\n\nmain();\nप्रत्येक Worker अपने स्वयं के थ्रेड में काम करता है, उसका अपना Event Loop होता है और वह