시퀀스와 이터레이터에는 실행 중에 중단할 수 없다는 제한이 있음
한계를 극복하려면 프로듀서를 사용해야 함
프로듀서의 사상과 사용법은 일시 중단 시퀀스/이터레이터와 비슷하지만
차이 존재
프로듀서에 대한 중요한 세부 사항
프로듀서는 값이 생성된 후 일시 중단되며, 새로운 값이 요청될 때 다시 재개
이는 일시 중단 시퀀스/이터레이터와 유사
프로듀서는 특정 CoroutineContext로 생성할 수 있음
전달되는 일시 중단 람다의 본문은 언제든지 일시 중단될 수 있음
어느 시점에서든 일시 중단할 수 있으므로 프로듀서의 값을 일시 중단 연산에서만 수신할 수 있음
채널을 사용해 작동하므로 데이터를 스트림처럼 생각할 수 있음
요소를 수신하면 스트림에서 요소가 제거
🛠️ 채널에 대해 .. 6장에 나온다고 한다 ..
val producer = GlobalScope.produce { send(1) } launch()와 async()와 같은 방식으로 CoroutineContext를 지정할 수 있다. val context = newSingleThreadContext("myThread") val producer2 = GlobalScope.produce(context){ send(1) } 이터레이터/시퀀스와 마찬가지로 타입을 지정할 수 있으며, 배출된 요소가 이를 준수하는 작동한다. val producer3: ReceiveChannel<Any> = GlobalScope.produce(context) { send(5) send("a") }
val context = newSingleThreadContext("myThread") val producer = GlobalScope.produce(context) { for(i in 0..9) send(i) } producer.consumeEach { println(it) }
val producer: ReceiveChannel<Any> = GlobalScope.produce() { send(5) send("a") } fun main(args: Array<String>) = runBlocking { println(producer.receive()) println(producer.receive()) }
producer.take(3).consumeEach { println(it) }
-> 왜 안됨?
↪ ReceiveChannel<E> 의 take() 는 ReceiveChannel<E> 를 반환
take() 는 중간 연산 이므로 종단 연산이 발생할 때 세 요소의 실제 값이 계산
종단 연산은 consumerEach()
// 10개 요소까지 배출할 수 있는 채널을 고려하면 코드는 실패 X producer.take(12).consumeEach { println(it) } // consumeEach는 얼마나 많은 요소를 가져오려 했는지 상관없이 // 더 이상 요소가 없으면 중지 val element = producer.receive() // 다른 요소에 별개의 receive()를 추가하면 앱이 중단