Flow 는 Cold stream 이며, emit 방출하는 코드와 collect 소비하는 코드가 같은 코루틴 내에 실행될 것을 기대한다.
-> 이는 데이터 흐름을 순차적으로 보장하고, 데이터 방출 및 수집 간의 상태를 쉽게 추적할 수 있도록 한다.
flow{} 블록 내부 코드는 동일한 CoroutineContext 에서 실행되도록 설계되었습니다.
다른 CoroutineContext 를 사용할 경우, Flow 일관성을 깨뜨릴 수 있다. 특히, Flow 는 순차적 데이터 흐름과 쓰레드 안정성을 보장하기 위해 설정된 제약이 있습니다.
만약 다른 CoroutineContext 에서 값을 방출하려고 하면 아래와 같은 에러가 발생한다.
val incorrectFlow = flow {
withContext(Dispatchers.IO) { // 다른 CoroutineContext
emit("This will cause an error!") // 오류 발생
}
}
java.lang.IllegalStateException: Flow invariant is violated..
1) 동일한 CoroutineContext 에서 emit 하기
val correctFlow = flow {
val result = withContext(Dispatchers.IO) { // 데이터를 가져올 때만 Context 변경
fetchDataFromNetwork() // 네트워크 호출
}
emit(result) // emit은 동일한 CoroutineContext에서 호출
}
2) callbackFlow 사용
val safeFlow = callbackFlow {
withContext(Dispatchers.IO) { // 다른 Context에서 값 생성
send("This is allowed!") // 안전하게 값 방출
}
awaitClose { /* 리소스 정리 */ }
}


번외) 면접에 자주나오는..
ColdFlow :