कोटलिन फ्लो | भाग 2

Apr 18 2023
इस लेख में हम कोटलिन प्रवाह को विस्तार से समझेंगे। इस लेख का भाग 1 पहले ही प्रकाशित हो चुका है जिसे आप यहाँ से देख सकते हैं।
Unsplash पर Marc Reichelt द्वारा फोटो

इस लेख में हम कोटलिन प्रवाह को विस्तार से समझेंगे।

इस लेख का भाग 1 पहले ही प्रकाशित हो चुका है जिसे आप यहाँ से देख सकते हैं।

कोटलिन फ्लो | भाग ---- पहला

यह श्रृंखला का भाग 2 है जिसमें निम्नलिखित विषयों को शामिल किया गया है:

  • प्रवाह रद्दीकरण
  • इंटरमीडिएट फ्लो ऑपरेटर्स
  • रूपांतरण ऑपरेटर
  • आकार सीमित ऑपरेटर
  • टर्मिनल फ्लो ऑपरेटर

कोटलिन में, फ्लो कैंसलेशन एक फ्लो के निष्पादन को रोकने की प्रक्रिया है जब इसकी आवश्यकता नहीं होती है। यह संसाधन रिसाव और अनावश्यक गणनाओं को रोकने के लिए उपयोगी हो सकता है।

प्रवाह को रद्द करने के लिए, आप cancel()फ़ंक्शन का उपयोग कर सकते हैं। इस फ़ंक्शन को इंटरफ़ेस पर एक एक्सटेंशन फ़ंक्शन के रूप में परिभाषित किया गया है Job, जिसे launch()फ़ंक्शन द्वारा लौटाया जाता है जब आप एक कोरआउट शुरू करते हैं। इसलिए, किसी प्रवाह को रद्द करने के लिए, आपके पास उस वस्तु का संदर्भ होना चाहिए Jobजो प्रवाह के शुरू होने पर वापस आ गई थी।

प्रवाह को रद्द करने के तरीके का एक उदाहरण यहां दिया गया है:

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

fun main() = runBlocking<Unit> {
    val flow = flow {
        for (i in 1..10) {
            delay(100)
            emit(i)
        }
    }

    val job = launch {
        flow.collect { println(it) }
    }

    delay(500)
    job.cancel()
}

500 मिलीसेकंड के बाद, हम द्वारा लौटाए गए ऑब्जेक्ट cancel()पर फ़ंक्शन को कॉल करते हैं । यह प्रवाह को रद्द कर देता है और किसी और उत्सर्जन को रोकता है। कोरूटीन जो प्रवाह मान एकत्र कर रहा था रद्द कर दिया जाएगा, और कार्यक्रम समाप्त हो जाएगा।Joblaunch()

ध्यान दें कि जब एक प्रवाह को रद्द कर दिया जाता है, तो रद्दीकरण को प्रवाह के स्रोत तक ऊपर की ओर प्रचारित किया जाता है। इस उदाहरण में, delay()प्रवाह के अंदर का फ़ंक्शन a को फेंक देगा CancellationException, जो प्रवाह को लॉन्च करने वाले कोरटाइन द्वारा पकड़ा जाएगा।

फ़्लो कैंसलेशन चेक का उपयोग करके फ़्लो को रद्द करने के अन्य तरीके

  1. रद्द करने योग्य में व्यस्त लूप उत्सर्जन मान
  2. fun foo(): Flow<Int> = flow { 
        for (i in 1..5) {
            println("Emitting $i") 
            emit(i) 
        }
    }
    
    fun main() = runBlocking<Unit> {
        foo().collect { value -> 
            if (value == 3) cancel()  
            println(value)
        } 
    }
    

    Emitting 1
    1
    Emitting 2
    2
    Emitting 3
    3
    Emitting 4
    Exception in thread "main" kotlinx.coroutines.JobCancellationException: BlockingCoroutine was cancelled; job="coroutine#1":BlockingCoroutine{Cancelled}@6d7b4f4c
    

    
    fun main() = runBlocking<Unit> {
        (1..5).asFlow().collect { value -> 
            if (value == 3) cancel()  
            println(value)
        } 
    }
    1
    2
    3
    4
    5
    Exception in thread "main" kotlinx.coroutines.JobCancellationException: BlockingCoroutine was cancelled; job="coroutine#1":BlockingCoroutine{Cancelled}@3327bd23\
    

प्रवाह को रद्द करने का दूसरा तरीका यह है कि cancellable()बाहर से प्रवाह को रद्द करने योग्य बनाने के लिए ऑपरेटर का उपयोग किया जाए। यहाँ एक उदाहरण है:

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

fun main() = runBlocking<Unit> {
    val flow = flow {
        for (i in 1..10) {
            delay(100)
            emit(i)
        }
    }

    val job = launch {
        flow.cancellable().collect { println(it) }
    }

    delay(500)
    job.cancel()
}

ध्यान दें कि cancellable()ऑपरेटर वास्तव में प्रवाह को रद्द नहीं करता है; यह केवल बाहर से प्रवाह को रद्द करना संभव बनाता है। प्रवाह केवल तभी रद्द किया जाएगा जब प्रवाह मान एकत्रित करने वाला कोरूटिन भी रद्द कर दिया गया हो।

इंटरमीडिएट फ्लो ऑपरेटर्स

ऑपरेटरों का उपयोग करके प्रवाह को रूपांतरित किया जा सकता है, ठीक उसी तरह जैसे आप संग्रह और अनुक्रम को रूपांतरित करते हैं। इंटरमीडिएट ऑपरेटरों को अपस्ट्रीम प्रवाह पर लागू किया जाता है और डाउनस्ट्रीम प्रवाह लौटाता है। ये ऑपरेटर ठंडे होते हैं, जैसे प्रवाह होते हैं। ऐसे ऑपरेटर को कॉल करना अपने आप में एक निलंबित कार्य नहीं है। यह तेजी से काम करता है, एक नए रूपांतरित प्रवाह की परिभाषा लौटाता है।

  1. filter:

val numbers = flowOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// filter out even numbers
val filteredNumbers = numbers.filter { it % 2 == 0 }
filteredNumbers.collect { println(it) } // output: 2 4 6 8 10

ऑपरेटर mapएक निर्दिष्ट फ़ंक्शन का उपयोग करके तत्वों को प्रवाह में बदल देता है। उदाहरण के लिए, आप mapतापमान को फ़ारेनहाइट से सेल्सियस में बदलने के लिए ऑपरेटर का उपयोग कर सकते हैं।

val temperaturesFahrenheit = flowOf(68, 73, 82, 79, 64, 57)
val temperaturesCelsius = temperaturesFahrenheit.map { (it - 32) * 5/9 }
temperaturesCelsius.collect { println(it) }
 // output: 20.0 22.77777777777778 27.77777777777778 26.11111111111111 17.77777777777778 13.88888888888889

ऑपरेटर flatMapConcatप्रत्येक तत्व को प्रवाह में दूसरे प्रवाह में बदल देता है और परिणामी प्रवाह को एकल आउटपुट प्रवाह में जोड़ता है। उदाहरण के लिए, आप flatMapConcatऑपरेटर का उपयोग कई CSV फ़ाइलों को पढ़ने और उनकी सामग्री को एक प्रवाह में जोड़ने के लिए कर सकते हैं।

val filenames = flowOf("file1.csv", "file2.csv", "file3.csv")
// read each file and concatenate their contents into a single flow
val contents = filenames.flatMapConcat { filename ->
    flow {
        // read contents of the file
        val fileContents = readFile(filename)
        // emit each line of the file as a separate element in the flow
        fileContents.lines().forEach { emit(it) }
    }
}
contents.collect { println(it) } // output: contents of file1.csv, contents of file2.csv, contents of file3.csv

ऑपरेटर distinctUntilChangedप्रवाह से लगातार डुप्लिकेट तत्वों को हटाता है। उदाहरण के लिए, आप पूर्णांकों के प्रवाह से लगातारdistinctUntilChanged डुप्लिकेट मानों को निकालने के लिए ऑपरेटर का उपयोग कर सकते हैं।

val numbers = flowOf(1, 2, 2, 3, 3, 3, 2, 2, 1)
// remove consecutive duplicates
val distinctNumbers = numbers.distinctUntilChanged()
distinctNumbers.collect { println(it) } // output: 1 2 3 2 1

ऑपरेटर takeप्रवाह में तत्वों की संख्या को निर्दिष्ट अधिकतम तक सीमित करता है। उदाहरण के लिए, आप takeऑपरेटर का उपयोग प्रवाह में तत्वों की संख्या को 5 तक सीमित करने के लिए कर सकते हैं।

val numbers = flowOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// limit to 5 elements
val limitedNumbers = numbers.take(5)
limitedNumbers.collect { println(it) } // output: 1 2 3 4 5

ऑपरेटर transformका उपयोग प्रवाह द्वारा उत्सर्जित तत्वों को एक नया प्रवाह उत्पन्न करने के लिए बदलने के लिए किया जाता है।

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

fun main() = runBlocking<Unit> {
    val numbers = flowOf(1, 2, 3, 4, 5)
    
    numbers
        .transform { value ->
            emit("Value: $value")
            emit("Double value: ${value * 2}")
        }
        .collect { println(it) }
}
Value: 1
Double value: 2
Value: 2
Double value: 4
Value: 3
Double value: 6
Value: 4
Double value: 8
Value: 5
Double value: 10

कोटलिन फ्लो में, कई ऑपरेटर हैं जिनका उपयोग प्रवाह में उत्सर्जित वस्तुओं के आकार को सीमित करने के लिए किया जा सकता है।

कोरटाइन में रद्दीकरण हमेशा एक अपवाद फेंक कर किया जाता है, ताकि try { ... } finally { ... }रद्दीकरण के मामले में सभी संसाधन-प्रबंधन कार्य (जैसे ब्लॉक) सामान्य रूप से संचालित हों।

  1. take(n: Int): यह ऑपरेटर पहले nतत्वों को प्रवाह से लेता है और फिर प्रवाह को रद्द कर देता है। यदि प्रवाह nतत्वों से कम उत्पादन करता है, तो यह उन सभी को उत्सर्जित करेगा।
  2. takeWhile(predicate: (T) -> Boolean): यह ऑपरेटर प्रवाह से तत्वों को लेता है जबकि प्रेडिकेट फ़ंक्शन वापस आता है true। जब विधेय वापस आता है false, तो प्रवाह रद्द हो जाता है।
  3. takeLast(n: Int)n: यह ऑपरेटर प्रवाह द्वारा उत्सर्जित अंतिम तत्वों को एकत्र करता है और फिर उन्हें उल्टे क्रम में उत्सर्जित करता है।
  4. import kotlinx.coroutines.flow.flowOf
    import kotlinx.coroutines.flow.takeLast
    import kotlinx.coroutines.runBlocking
    
    fun main() = runBlocking {
        val numbers = flowOf(1, 2, 3, 4, 5)
        val lastThreeNumbers = numbers.takeLast(3)
        lastThreeNumbers.collect { println(it) } // prints 3, 4, 5
    }
    

    import kotlinx.coroutines.flow.flowOf
    import kotlinx.coroutines.flow.drop
    import kotlinx.coroutines.flow.collect
    import kotlinx.coroutines.runBlocking
    
    fun main() = runBlocking {
        val numbers = flowOf(1, 2, 3, 4, 5)
        numbers.drop(2).collect { println(it) } // prints 3, 4, 5
    }
    

टर्मिनल फ्लो ऑपरेटर

टर्मिनल ऑपरेटर कोटलिन फ्लो में ऑपरेटर होते हैं जो प्रवाह द्वारा उत्सर्जित तत्वों का उपभोग करते हैं और परिणाम उत्पन्न करते हैं। कलेक्ट सबसे ज्यादा इस्तेमाल किया जाने वाला है।

  1. toList(): यह ऑपरेटर प्रवाह द्वारा उत्सर्जित सभी तत्वों को एक सूची में एकत्र करता है और सूची को वापस करता है।
  2. toSet(): यह ऑपरेटर प्रवाह द्वारा उत्सर्जित सभी तत्वों को एक सेट में एकत्र करता है और सेट को वापस करता है।
  3. reduce(): यह ऑपरेटर प्रवाह द्वारा उत्सर्जित तत्वों पर दिए गए फ़ंक्शन को लागू करता है और एकल मान लौटाता है। फ़ंक्शन दो तर्क लेता है, जिनमें से पहला अब तक संचित परिणाम है, और दूसरा प्रवाह द्वारा उत्सर्जित अगला तत्व है।
  4. fold(): यह ऑपरेटर के समान है reduce(), लेकिन यह आपको संचित परिणाम के लिए प्रारंभिक मान निर्दिष्ट करने की अनुमति देता है।
  5. count(): यह ऑपरेटर प्रवाह द्वारा उत्सर्जित तत्वों की संख्या की गणना करता है और गिनती को पूर्णांक के रूप में लौटाता है।
  6. min(), max(): ये ऑपरेटर क्रमशः प्रवाह द्वारा उत्सर्जित न्यूनतम या अधिकतम तत्व पाते हैं।
  7. collect(): यह ऑपरेटर प्रवाह द्वारा उत्सर्जित तत्वों का उपभोग करता है और प्रत्येक तत्व पर एक क्रिया करता है। यह परिणाम नहीं देता है, लेकिन अक्सर साइड इफेक्ट के लिए उपयोग किया जाता है।
  8. import kotlinx.coroutines.flow.flowOf
    import kotlinx.coroutines.flow.*
    import kotlinx.coroutines.runBlocking
    
    fun main() = runBlocking {
        val numbers = flowOf(1, 2, 3, 4, 5)
    
        val list = numbers.toList()
        println("List of numbers: $list")
    
        val set = numbers.toSet()
        println("Set of numbers: $set")
    
        val sum = numbers.reduce { accumulator, value -> accumulator + value }
        println("Sum of numbers: $sum")
    
        val product = numbers.fold(1) { accumulator, value -> accumulator * value }
        println("Product of numbers: $product")
    
        val count = numbers.count()
        println("Count of numbers: $count")
    
        val min = numbers.min()
        println("Minimum number: $min")
    
        val max = numbers.max()
        println("Maximum number: $max")
    
        numbers.collect { println("Processing $it") }
    }
    List of numbers: [1, 2, 3, 4, 5]
    Set of numbers: [1, 2, 3, 4, 5]
    Sum of numbers: 15
    Product of numbers: 120
    Count of numbers: 5
    Minimum number: 1
    Maximum number: 5
    Processing 1
    Processing 2
    Processing 3
    Processing 4
    Processing 5
    

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

आशा है कि यह लेख आपके लिए मददगार रहा होगा।

यदि आपके पास कोई प्रतिक्रिया या प्रश्न हैं तो कृपया मुझे [email protected] पर वापस लिखें। इस लेख को खोजने में दूसरों की मदद करने के लिए आपकी तालियों की वास्तव में सराहना की जाती है ।