Kotlin में रिएक्टिव प्रोग्रामिंग: kotlinx.coroutines और Flow लाइब्रेरी

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

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

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

Kotlin में रिएक्टिव प्रोग्रामिंग: kotlinx.coroutines और Flow की शक्ति

रिएक्टिव प्रोग्रामिंग एक ऐसी पैराडाइम है जो डेटा स्ट्रीम के एसिंक्रोनस प्रोसेसिंग और बदलावों के प्रसार पर केंद्रित है। Kotlin इकोसिस्टम में, रिएक्टिव पैटर्न को लागू करने का मुख्य टूल kotlinx.coroutines लाइब्रेरी है, और विशेष रूप से इसका Flow कंपोनेंट। RxJava के विपरीत, Flow कोरूटीन के साथ गहराई से एकीकृत है, जो कोड को अधिक संक्षिप्त और सुरक्षित बनाता है।

Flow की मुख्य अवधारणाएँ

Flow एक कोल्ड एसिंक्रोनस डेटा स्ट्रीम है जो क्रमिक रूप से मान उत्सर्जित करता है। यह निम्नलिखित सुविधाएँ प्रदान करता है:

  • कोल्ड स्ट्रीम — डेटा केवल तभी जनरेट होना शुरू होता है जब कोई सब्सक्राइबर (टर्मिनल ऑपरेटर) मौजूद हो।
  • एक्ज़ीक्यूशन कॉन्टेक्स्ट — स्ट्रीम विभिन्न कोरूटीन डिस्पैचर्स के बीच स्विच कर सकती है।
  • कोरूटीन के माध्यम से कैंसलेशन — पैरेंट कोरूटीन को कैंसल करने से Flow स्वचालित रूप से समाप्त हो जाता है।

इंस्टॉलेशन और सेटअप

Flow का उपयोग करने के लिए, build.gradle.kts में डिपेंडेंसी जोड़ें:

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
}

Flow बनाना और उपभोग करना

आइए देरी के साथ एक सरल नंबर स्ट्रीम बनाएँ:

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun simpleFlow(): Flow<Int> = flow {
    for (i in 1..5) {
        delay(100) // एसिंक्रोनस कार्य का अनुकरण
        emit(i)    // मान उत्सर्जित करें
    }
}

fun main() = runBlocking {
    simpleFlow().collect { value ->
        println("प्राप्त: $value")
    }
}

इस उदाहरण में, flow { ... } एक कोल्ड स्ट्रीम बनाता है, और collect एक टर्मिनल ऑपरेटर है जो निष्पादन शुरू करता है।

ऑपरेटरों के साथ डेटा ट्रांसफॉर्मेशन

Flow RxJava के समान ऑपरेटरों का एक समृद्ध सेट प्रदान करता है:

  • map — प्रत्येक मान को बदलता है।
  • filter — शर्त के अनुसार मानों को फ़िल्टर करता है।
  • flatMapConcat — स्ट्रीम को क्रमिक रूप से जोड़ता है।
  • catch — स्ट्रीम के अंदर अपवादों को संभालता है।

ऑपरेटरों के साथ उदाहरण:

fun transformFlow(): Flow<String> = flow {
    emit("Kotlin")
    emit("Java")
    emit("Python")
}.map { it.lowercase() }
 .filter { it.startsWith("k") }

fun main() = runBlocking {
    transformFlow().collect { println(it) }
    // आउटपुट: kotlin
}

एरर हैंडलिंग और समाप्ति

Flow catch के साथ अपवादों को आसानी से संभालने और onCompletion के माध्यम से समाप्ति क्रियाएँ करने की अनुमति देता है:

fun errorProneFlow(): Flow<Int> = flow {
    emit(1)
    emit(2)
    throw RuntimeException("त्रुटि!")
    emit(3) // निष्पादित नहीं होगा
}

fun main() = runBlocking {
    errorProneFlow()
        .catch { e -> println("त्रुटि पकड़ी गई: ${e.message}") }
        .onCompletion { println("स्ट्रीम समाप्त") }
        .collect { println(it) }
}
// आउटपुट: 1, 2, त्रुटि पकड़ी गई: त्रुटि!, स्ट्रीम समाप्त

हॉट स्ट्रीम: StateFlow और SharedFlow

कोल्ड Flow के विपरीत, StateFlow और SharedFlow हॉट स्ट्रीम हैं जो स्थिति संग्रहीत करते हैं और कई सब्सक्राइबर हो सकते हैं।

StateFlow

इसका उपयोग स्थिति को संग्रहीत और देखने के लिए किया जाता है (जैसे, ViewModel में):

class CounterViewModel {
    private val _counter = MutableStateFlow(0)
    val counter: StateFlow<Int> = _counter.asStateFlow()

    fun increment() {
        _counter.value++
    }
}

// Activity या Fragment में
lifecycleScope.launch {
    viewModel.counter.collect { value ->
        textView.text = "गणना: $value"
    }
}

SharedFlow

यह उन घटनाओं के लिए उपयुक्त है जिन्हें केवल एक बार संसाधित किया जाना चाहिए (जैसे, नेविगेशन कमांड):

अनुशंसाएँ