callbackFlow는
callbackFlow는 코루틴의 Flow API를 사용해 콜백 기반의 비동기 패턴을 선언적인 스트림으로 변환할 수 있게 해주는 함수다.
flow블록 내에서는 context를 하나만 사용할 수 있는데,
withContext(Dispatcher.Main) {
flowWithIOContext()
.map{ .. }
.flowOn(Dispatcher.IO)
.map{ .. }
.flowOn(Dispatcher.Default)
}
flowOn을 통해 context를 바꾸어 줄 수 있지만 하나의 블록 안에서 동적으로 바꾸거나 콜백 함수 등에서는 사용할 수 없다.
이를 해결하기 위해 callbackFlow나 channelFlow를 사용한다.
lifecycleScope.launch {
flow<Unit>{
view.setOnClickListener {
this.emit(Unit)
}
}
}
flow에서 setOnClickListener와 같은 콜백 함수에서 emit을 사용하게 되면 컴파일러 에러가 발생한다.
콜백 안에서 코루틴 스코프가 정의되지 않았기 때문인데 만약 코루틴 스코프를 지정한다고 해도 flow안에서는 스코프를 선언할 수 없어 또 에러가 발생한다.
lifecycleScope.launch {
callbackFlow<Unit> {
view.setOnClickListener {
offer(Unit)
launch(Dispatchers.Main){
send(Unit)
}
close()
}
awaitClose()
}.collect {
Unit
}
}
callbackFlow에서 동기로 값을 보낸다면 send 비동기로 값을 내보낸다면 offer를 사용한다.
awaitClose는 람다 형식의 콜백을 인자로 받아 close 될때 실행되는 콜백 함수를 정의할 수 있다.
awaitClose {
composeDispasable.dispose()
}