एक थ्रेड जो सब पर राज करे: जावास्क्रिप्ट में कंकरेंसी के बारे में मिथक और सच्चाई
\n\nबहुत समय पहले, स्थिर वेबसाइटों और "सबमिट" बटनों के युग में, जो पूरे इंटरफ़ेस को ब्लॉक कर देते थे, जावास्क्रिप्ट एक ही थ्रेड में खुशी से रहता था। यह उसके लिए पर्याप्त था: अनुरोध आया - निष्पादित हुआ, अनुरोध गया - इंटरफ़ेस रुक गया। लेकिन समय बदल गया है। आज हम वेब एप्लिकेशन से तत्काल प्रतिक्रिया की उम्मीद करते हैं: स्क्रॉल धीमा नहीं होना चाहिए, एनिमेशन स्मूथ होने चाहिए, और डेटा लोडिंग अदृश्य होनी चाहिए। और यहीं पर कंकरेंसी खेल में आती है।
\n\nकई डेवलपर्स कंकरेंसी (concurrency) को पैरेललिज़्म (parallelism) समझ लेते हैं। जावास्क्रिप्ट में, विशेष रूप से ब्राउज़र में, हम अक्सर पहले वाले से निपटते हैं। यह एक बाजीगर की तरह है: वह सभी गेंदों को एक साथ हवा में नहीं रखता (यह पैरेललिज़्म है), लेकिन वह उनके बीच इतनी चतुराई से स्विच करता है कि एक साथ होने का भ्रम पैदा होता है। इस लेख में, हम JS में कंकरेंसी को व्यवस्थित करने के लिए तीन प्रमुख उपकरणों पर चर्चा करेंगे: async/await, गोरूटीन्स (जनरेटर और Web Workers के माध्यम से) और क्लासिक थ्रेड्स। चलिए शुरू करते हैं!
Async/Await: सुरुचिपूर्ण एसिंक्रोनस कोड
\n\nasync/await प्रॉमिसेस (Promises) पर एक सिंटैक्टिक शुगर है, जो ES2017 में आया था। यह कोड को मल्टीथ्रेडेड नहीं बनाता, लेकिन इसे एसिंक्रोनस बनाता है। जब आप await लिखते हैं, जावास्क्रिप्ट इस फंक्शन में "सो जाता है", अन्य कार्यों के लिए थ्रेड को मुक्त करता है। जैसे ही प्रॉमिस हल होता है, फंक्शन जागता है और निष्पादन जारी रखता है। यह I/O ऑपरेशनों के लिए एक आदर्श उपकरण है: API अनुरोध, फ़ाइल पढ़ना, टाइमर।
सरल उदाहरण: सर्वर से डेटा लोड करना
\n\n// फंक्शन जो Promise लौटाता है\nfunction fetchUser(id) {\n return new Promise((resolve) => {\n setTimeout(() => resolve({ id, name: 'अलेक्सेई' }), 1000);\n });\n}\n\n// एसिंक्रोनस फंक्शन\nasync function loadUserProfile(userId) {\n console.log('लोडिंग शुरू कर रहे हैं...');\n const user = await fetchUser(userId);\n console.log('उपयोगकर्ता लोड हुआ:', user.name);\n return user;\n}\n\nloadUserProfile(42);\nconsole.log('यह कोड तुरंत निष्पादित होगा, लोडिंग की प्रतीक्षा किए बिना!');\n\n\nध्यान दें: console.log('यह कोड तुरंत निष्पादित होगा...'), console.log('उपयोगकर्ता लोड हुआ') से पहले चलेगा। थ्रेड ब्लॉक नहीं होता - यही कंकरेंसी क्रियान्वित है।
एरर हैंडलिंग
\n\nasync function fetchWithRetry(url, retries = 3) {\n for (let i = 0; i < retries; i++) {\n try {\n const response = await fetch(url);\n if (!response.ok) throw new Error('HTTP त्रुटि');\n return await response.json();\n } catch (error) {\n if (i === retries - 1) throw error;\n console.log(`प्रयास ${i + 1} विफल रहा, पुनः प्रयास कर रहे हैं...`);\n }\n }\n}\n\n\nकब उपयोग करें: बाहरी संसाधनों (API, डेटाबेस, Node.js में फ़ाइल सिस्टम) के साथ कोई भी ऑपरेशन। async/await एसिंक्रोनस कोड के लिए आपका मुख्य उपकरण है।
जावास्क्रिप्ट में गोरूटीन्स: मिथक या वास्तविकता?
\n\n"गोरूटीन" शब्द Go से आया है और एक हल्के-वजन वाले निष्पादन थ्रेड को दर्शाता है। जावास्क्रिप्ट में मूल गोरूटीन्स नहीं हैं, लेकिन इसमें जनरेटर (Generator Functions) और Web Workers हैं, जो समान व्यवहार का अनुकरण कर सकते हैं। जनरेटर फंक्शन के निष्पादन को रोकने और फिर से शुरू करने की अनुमति देते हैं, जो निष्पादन प्रवाह पर नियंत्रण प्रदान करता है।
\n\nकंकरेंसी के आधार के रूप में जनरेटर
\n\nfunction* taskGenerator() {\n console.log('कार्य 1 शुरू कर रहे हैं');\n yield 'कार्य 1 पूर्ण हुआ';\n console.log('कार्य 2 शुरू कर रहे हैं');\n yield 'कार्य 2 पूर्ण हुआ';\n console.log('कार्य 3 शुरू कर रहे हैं');\n yield 'कार्य 3 पूर्ण हुआ';\n}\n\nconst iterator = taskGenerator();\nconsole.log(iterator.next().value); // कार्य 1 निष्पादित करता है\n// इस बिंदु पर आप कुछ और कर सकते हैं\nconsole.log(iterator.next().value); // कार्य 2 निष्पादित करता है\nconsol