Android 공부/Coroutine

[XX캠퍼스] 08.Kotlin Coroutines & Flow ( Flow 기초 )

Machine_웅 2022. 7. 26. 17:23
728x90
반응형

처음만나보는 플로우

Flow는 코틀린에서 쓸 수 있는 비동기 스트림입니다

- 코루틴을 사용하여 코틀린에서 쓸수 있는 스트림

- 스트림이기때문에 변화를 추적할 수 있다. 

import kotlin.random.Random
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun flowSomething(): Flow<Int> = flow {
    repeat(10) {
        emit(Random.nextInt(0, 500))
        delay(10L)
    }
}

fun main() = runBlocking {
    flowSomething().collect { value ->
        println(value)
    }
}

 Flow<Int> //  Flow< 방출할 값의 종류 >

 

flow 플로우 빌더 함수를 이용해서 코드블록을 구성하고

emit을 호출해서 스트림에 데이터를 흘려 보냅니다.

플로우는 콜드 스트림이기 때문에 요청 측에서 collect를 호출해야 값을 발생하기 시작합니다.

 

flow  플로우 빌더로 코드블록구성 -> emit 데이터 방출 -> collect 호출 -> 값발생 

 

  • 콜드 스트림 - 요청이 있는 경우에 보통 1:1로 값을 전달하기 시작. ( collect 를 하면 값이 발생 ) 
  •  
  • 핫 스트림 - 0개 이상의 상대를 향해 지속적으로 값을 전달.

 


플로우 취소 withTimeoutOrNull

코루틴 시간에 배웠던 withTimeoutOrNull을 이용해 간단히 취소할 수 있습니다.

 

import kotlin.random.Random
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun flowSomething(): Flow<Int> = flow {
    repeat(10) {
        emit(Random.nextInt(0, 500))
        delay(100L)
    }
}

fun main() = runBlocking<Unit> {
    val result = withTimeoutOrNull(500L) {
        flowSomething().collect { value ->
            println(value)
        }
        true
    } ?: false
    if (!result) {
        println("취소되었습니다.")
    }
}

 

 val result = withTimeoutOrNull(500L) { // 500L 일때 타임아웃, 
        flowSomething().collect { value ->
            println(value)
        }
        true
    } ?: false // 엘비스 연산자로 null 이 false 로 바뀐다. 

 

* withTimeout 를 사용하면 예외가 발생한다.  그예외를 가지고 처리 한다. 

 


플로우 빌더 flowOf

flow

flowOf

asFlow  등의 플로우 빌더가 있습니다.

 

 

flowOf는 여러 값을 인자로 전달해 플로우를 만듭니다.

import kotlin.random.Random
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking<Unit> {
    flowOf(1, 2, 3, 4, 5).collect { value ->
        println(value)
    }
    
    // 위와 동일하다. 
    flow {
    	emit(1)
        emit(2)
        emit(3)
        emit(4)
        emit(5)
    }.collect {println(it)} 
}

 

asFlow컬렉션이나 시퀀스를 전달해 플로우를 만들 수 있습니다.

import kotlin.random.Random
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking<Unit> {
    listOf(1, 2, 3, 4, 5).asFlow().collect { value ->
        println(value)
    }
    (6..10).asFlow().collect {
        println(it)
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형