launch/join बनाम async/await Kotlin में: 2025 में क्या चुनें?

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

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

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

launch/join बनाम async/await Kotlin में: 2025 में क्या चुनें? उदाहरणों के साथ पूर्ण विश्लेषण

\n\n

नमस्ते, सहकर्मी! यदि आपने कभी Kotlin में coroutines लिखे हैं, तो आपने निश्चित रूप से यह प्रश्न पूछा होगा: "आखिर launch और async में क्या अंतर है? और इस रहस्यमय join की क्या आवश्यकता है?" यह प्रश्न Stack Overflow पर एक वास्तविक हिट है, जिसे हजारों बार देखा गया है। और यह कोई संयोग नहीं है: पहली नज़र में दोनों उपकरण एक ही काम करते हैं - एक पृष्ठभूमि कार्य शुरू करना। लेकिन शैतान, हमेशा की तरह, विवरण में है।

\n\n

2025 में, जब Kotlin coroutines Android विकास और बैकएंड में मुख्यधारा बन गए हैं, इन अंतरों को समझना केवल एक इच्छा नहीं, बल्कि स्वच्छ, सुरक्षित और कुशल कोड लिखने के लिए एक आवश्यकता है। इस लेख में, हम केवल शुष्क तथ्यों को सूचीबद्ध नहीं करेंगे। हम वास्तविक परिदृश्यों का विश्लेषण करेंगे, कोड देखेंगे और सर्वोत्तम अभ्यास निकालेंगे जिन्हें आप अभी अपनी परियोजनाओं में सुरक्षित रूप से लागू कर सकते हैं।

\n\n

चलिए शुरू करते हैं!

\n\n

launch: "शुरू करो और भूल जाओ"

\n\n

फ़ंक्शन launch शायद coroutine शुरू करने का सबसे सरल तरीका है। यह एक नया coroutine बनाता है जो कोई परिणाम नहीं लौटाता। इसका कार्य कुछ काम करना है: UI अपडेट करना, लॉग भेजना, फ़ाइल में डेटा लिखना। वापसी मान का प्रकार Job है। यह एक कूरियर को कार्य देने जैसा है: "पार्सल पहुंचाओ और वापस आओ, रिपोर्ट की आवश्यकता नहीं है"।

\n\n

विधि join आपको इस coroutine के पूरा होने की प्रतीक्षा करने की अनुमति देती है। यह वर्तमान coroutine के निष्पादन को तब तक रोकता है जब तक कि join को कॉल करने वाला job समाप्त नहीं हो जाता।

\n\n

एक उदाहरण पर विचार करें। मान लीजिए, हमें समानांतर में दो चित्र लोड करने हैं और फिर उन्हें संयोजित करना है। launch और join के साथ यह इस प्रकार दिखेगा:

\n\n
import kotlinx.coroutines.*\n\nsuspend fun loadImage(url: String): Image {\n    // लोडिंग का अनुकरण\n    delay(1000)\n    return Image(url)\n}\n\ndata class Image(val url: String)\n\nsuspend fun loadTwoImagesWithLaunch() = coroutineScope {\n    var image1: Image? = null\n    var image2: Image? = null\n\n    val job1 = launch {\n        image1 = loadImage("https://example.com/img1.png")\n    }\n\n    val job2 = launch {\n        image2 = loadImage("https://example.com/img2.png")\n    }\n\n    // दोनों कार्यों की प्रतीक्षा करें\n    job1.join()\n    job2.join()\n\n    // अब image1 और image2 निश्चित रूप से लोड हो चुके हैं\n    println("Images loaded: $image1 and $image2")\n}
\n\n

यहाँ क्या महत्वपूर्ण है? हम परिणाम को सहेजने के लिए परिवर्तनीय चर (var) का उपयोग करते हैं। यह बहुत सुंदर नहीं है और थ्रेड्स के साथ समस्याएँ पैदा कर सकता है, हालाँकि coroutines एक ही थ्रेड के भीतर काम करते हैं। लेकिन मुख्य नुकसान यह है कि हम सीधे मान वापस करने के लिए launch का उपयोग नहीं कर सकते।

\n\n

async: "शुरू करो और परिणाम प्राप्त करो"

\n\n

जबकि async पहले से ही "बिज़नेस क्लास" है। यह एक coroutine बनाता है जो परिणाम लौटाता है Deferred<T> ऑब्जेक्ट के रूप में। यह टैक्सी बुक करने जैसा है: आप प्रतीक्षा करते हैं, और आपको केवल यात्रा का तथ्य नहीं, बल्कि एक विशिष्ट परिणाम मिलता है - आप गंतव्य पर हैं। यह परिणाम प्राप्त करने के लिए await() का उपयोग किया जाता है।

\n\n

चित्र लोड करने का वही उदाहरण, लेकिन async/await के उपयोग से, अधिक सुरुचिपूर्ण हो जाता है:

\n\n
import kotlinx.coroutines.*\n\nsuspend fun loadImage(url: String): Image {\n    delay(1000)\n    return Image(url)\n}\n\ndata class Image(val url: String)\n\nsuspend fun loadTwoImagesWithAsync() = coroutineScope {\n    val deferred1 = async { loadImage("https://example.com/img1.png") }\n    val deferred2 = async { loadImage("https://example.com/img2.png") }\n\n    // await() coroutine को तब तक रोकता है जब तक परिणाम प्राप्त न हो जाए\n    val image1 = deferred1.await()\n    val image2 = deferred2.await()\n\n    println("Images loaded: $image1 and $image2")\n}
\n\n

अंतर महसूस कर रहे हैं? कोई var नहीं, कोई मैन्युअल प्रबंधन नहीं। सब कुछ साफ है,

ब्लॉग

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