Swift में एसिंक्रोनस प्रोग्रामिंग का परिचय
आधुनिक मोबाइल और डेस्कटॉप एप्लिकेशन को प्रतिक्रियाशील और तेज़ होना चाहिए। कोई भी यह पसंद नहीं करता कि नेटवर्क से डेटा लोड करते समय या बड़ी फ़ाइल प्रोसेस करते समय इंटरफ़ेस हैंग हो जाए। यहीं पर एसिंक्रोनस प्रोग्रामिंग मददगार साबित होती है। Swift में, संस्करण 5.5 से शुरू करके, एसिंक्रोनसिटी के साथ काम करने के लिए एक शक्तिशाली और सहज टूलकिट आया है — async/await, Task और Actor।
इस गाइड में, हम iOS और macOS के लिए Swift में एसिंक्रोनस प्रोग्रामिंग की मूल बातें समझेंगे। आप सीखेंगे कि कॉलबैक (callback hell) के बिना एसिंक्रोनस कोड कैसे लिखें, थ्रेड्स को सही तरीके से कैसे प्रबंधित करें और रेस कंडीशन से कैसे बचें। यह सामग्री शुरुआती डेवलपर्स के लिए है जो Swift सिंटैक्स की मूल बातें पहले से जानते हैं।
एसिंक्रोनस प्रोग्रामिंग क्या है और इसकी आवश्यकता क्यों है?
कल्पना करें कि आपका एप्लिकेशन रसोई में एक रसोइया है। यदि रसोइया केतली के उबलने का इंतज़ार करेगा और कुछ नहीं करेगा, तो दोपहर का भोजन लंबा खिंच जाएगा। एसिंक्रोनस प्रोग्रामिंग 'रसोइया' (मुख्य थ्रेड) को केतली को चढ़ाने और उसके उबलने का इंतज़ार किए बिना, सलाद काटने में लगने की अनुमति देती है। जब केतली उबल जाएगी, रसोइया उसके पास वापस आएगा।
iOS के संदर्भ में, इसका मतलब है कि भारी ऑपरेशन (इमेज लोड करना, JSON पार्स करना, डेटाबेस के साथ काम करना) बैकग्राउंड में निष्पादित होते हैं, मुख्य थ्रेड को ब्लॉक नहीं करते जो इंटरफ़ेस को अपडेट करने के लिए जिम्मेदार है। यदि ऐसा नहीं किया जाता है, तो एप्लिकेशन 'हैंग' हो जाएगा और जल्द ही सिस्टम द्वारा जबरन बंद कर दिया जाएगा।
पुराने दृष्टिकोण की समस्या: कॉलबैक और GCD
async/await के आगमन से पहले, डेवलपर्स Grand Central Dispatch (GCD) और क्लोजर (कॉलबैक) का उपयोग करते थे। इससे तथाकथित 'कॉलबैक नरक' होता था — कोड के नेस्टेड ब्लॉक जिन्हें पढ़ना, डीबग करना और बनाए रखना मुश्किल था।
// GCD और क्लोजर के साथ पुरानी शैलीfunc fetchUserData(completion: @escaping (User?) -> Void) { DispatchQueue.global().async { // लंबा ऑपरेशन let user = User(name: "इवान") DispatchQueue.main.async { completion(user) } }}
fetchUserData { user in guard let user = user else { return } fetchUserPosts(userId: user.id) { posts in // एक और नेस्टेड कॉलबैक print(posts) }}आधुनिक Swift कहीं अधिक सुरुचिपूर्ण समाधान प्रदान करता है।
Swift Concurrency की मूल बातें: async/await
एसिंक्रोनस फ़ंक्शन घोषित करना
किसी फ़ंक्शन को एसिंक्रोनस बनाने के लिए, पैरामीटर सूची के बाद कीवर्ड async जोड़ें। ऐसे फ़ंक्शन को कॉल करने के लिए कीवर्ड await का उपयोग करना होगा।
// एसिंक्रोनस फ़ंक्शनfunc fetchImage(from url: URL) async throws -> UIImage { let (data, _) = try await URLSession.shared.data(from: url) guard let image = UIImage(data: data) else { throw URLError(.badServerResponse) } return image}
// फ़ंक्शन को कॉल करनाTask { do { let image = try await fetchImage(from: url) self.imageView.image = image } catch { print("लोड करने में त्रुटि: \\(error)") }}ध्यान दें: URLSession.shared.data(from:) — यह Apple का पहले से तैयार एसिंक्रोनस फ़ंक्शन है। हम इसे केवल await के साथ कॉल करते हैं, और डेटा लोड होने तक थ्रेड अन्य कार्यों के लिए मुक्त हो जाता है।
अनुक्रमिक और समानांतर कॉल
आप एसिंक्रोनस फ़ंक्शन को अनुक्रमिक या समानांतर रूप से कॉल कर सकते हैं।
// अनुक्रमिक कॉल: दूसरा अनुरोध पहले की प्रतीक्षा करता हैlet user = try await fetchUser(id: 1)let posts = try await fetchPosts(for: user.id)
// समानांतर कॉल: दोनों अनुरोध एक साथ निष्पादित होते हैंasync let user = fetchUser(id: 1)async let posts = fetchPosts(for: 1)let (resultUser, resultPosts) = try await (user, posts)समानांतर मोड में, दोनों अनुरोध एक साथ शुरू होते हैं, जो