"मैं फंक्शन चलाता हूँ, और वह undefined लौटाता है!" — क्या यह दर्द आपको भी है?
\nसोचिए: आप JavaScript में कोड लिख रहे हैं, API को request भेजते हैं, डेटा का इंतज़ार करते हैं… और जवाब में मिलता है undefined। या उससे भी बुरा — Promise {<pending>}। हाथ ढीले हो जाते हैं, ब्राउज़र बंद करके संन्यास लेने का मन करता है।
रुकिए! यह समस्या अनुभवी डेवलपर्स को भी परेशान करती है। कोई आश्चर्य नहीं कि Stack Overflow पर सवाल "How do I return the response from an asynchronous call?" के हज़ारों व्यूज़ और सैकड़ों जवाब हैं। आज हम इसे हमेशा के लिए समझ लेंगे।
\nइस लेख में आप जानेंगे:
\n- \n
returnआपकी सोच के मुताबिक क्यों काम नहीं करता \n - Callbacks, Promises और
async/awaitसे एसिंक्रोनसिटी को कैसे काबू करें \n - आपके प्रोजेक्ट के लिए कौन सा तरीका सबसे अच्छा है \n
चलिए शुरू करते हैं!
\n\nreturn डेटा क्यों नहीं लौटाता?
\nसीधे मुद्दे पर आते हैं। यह रहा एक क्लासिक उदाहरण:
\n\nfunction getUserData(userId) {\n fetch(`https://api.example.com/users/${userId}`)\n .then(response => response.json())\n .then(data => {\n return data; // लगता है सब ठीक है, है ना?\n });\n}\n\nconst user = getUserData(42);\nconsole.log(user); // undefined\n\nपरिचित लग रहा है? आपने .then() के अंदर return data लिखा, लेकिन बाहर undefined मिला। ऐसा क्यों?
JavaScript सिंगल-थ्रेडेड और नॉन-ब्लॉकिंग है। जब आप fetch कॉल करते हैं, तो वह सर्वर से जवाब का इंतज़ार नहीं करता। इसके बजाय, वह callback को एक तरफ रख देता है और तुरंत अगली लाइन पर चला जाता है। और अगली लाइन है console.log(user), जहाँ user अभी तक परिभाषित नहीं हुआ है।
आपका getUserData फंक्शन सर्वर से जवाब आने से पहले ही खत्म हो जाता है। वह कुछ भी return नहीं करता (undefined लौटाता है), और डेटा हवा में लटका रहता है।
इसे कैसे ठीक करें? तीन मुख्य तरीके हैं।
\n\nतरीका 1: Callbacks — एसिंक्रोनसिटी के दादा
\nपहले के ज़माने में, Promises के आने से पहले, सभी एसिंक्रोनस ऑपरेशन callbacks के ज़रिए होते थे। आप एक फंक्शन पास करते हैं, जो डेटा आने पर कॉल होगा।
\n\nfunction getUserData(userId, callback) {\n fetch(`https://api.example.com/users/${userId}`)\n .then(response => response.json())\n .then(data => {\n callback(data); // डेटा के साथ callback कॉल करें\n })\n .catch(error => {\n callback(null, error); // या error पास करें\n });\n}\n\n// उपयोग:\ngetUserData(42, (data, error) => {\n if (error) {\n console.error('त्रुटि:', error);\n return;\n }\n console.log('उपयोगकर्ता डेटा:', data);\n});\n\nफायदे: सरल, हर जगह काम करता है।
\nनुकसान: अगर कई callbacks एक-दूसरे के अंदर हों, तो "callback hell" बन जाता है। कोड पढ़ना मुश्किल हो जाता है।
\n\ngetUserData(42, (data1) => {\n getPosts(data1.id, (data2) => {\n getComments(data2[0].id, (data3) => {\n // ... और ऐसे ही चलता रहता है\n });\n });\n});\n\nआधुनिक JavaScript इससे दूर हो गया है। लेकिन callbacks को समझना ज़रूरी है — ये बाकी सभी तरीकों की नींव हैं।
\n\nतरीका 2: Promises — पढ़ने लायक कोड के उद्धारकर्ता
\nPromise एक ऐसा ऑब्जेक्ट है जो भविष्य में कोई मान लौटाने का "वादा" करता है। इसकी तीन अवस्थाएँ होती हैं: pending (प्रतीक्षा), fulfilled (पूरा हुआ) और rejected (अस्वीकृत)।
अपने उदाहरण पर वापस आते हैं। Callback के बजाय, हम Promise को ही return करते हैं:
\n\nfunction getUserData(userId) {\n return fetch(`https://api.example.com/users/${userId}`)\n .then(response => {\n if (!response.ok) {\n throw new Error('नेटवर्क ठीक नहीं है');\n }\n return response.json();\n });\n}\n\n// उपयोग:\nconst userPromise = getUserData(42);\n\nuserPromise\n .then(data => {\n console.log('उपयोगकर्ता डेटा:', data);\n })\n