I have a really specific use case and I guess I ne...
# coroutines
l
I have a really specific use case and I guess I need something to pause and resume the emission of a flow multiple times. To be more concrete: I need to pause a flow to wait for a confirmation from another flow before emitting the next item. Any ideas how to solve this?
j
That is how suspend works by default
Copy code
suspend fun main() {
     val something = someSuspend()
     … // this will not be executed until someSuspend() ends
}
l
I have 2 independent flows. Flow1 has to wait for a specific piece of code of flow2 to be confirmed before emitting
I have adjusted my question, was a bit misleading
j
I am on mobile but probably a function like
zip
or something similar can help you
c
You might consider re-organizing your logic a bit. Rather than having multiple independent flows relying on the state of each other, consider more an an Actor or MVI pattern. You have one job that sends a “message” to be processed. Once that finishes, it sends a message to another, and so on. In your use-case, instead of flow1 doing some processing, then sending a job to flow2, and then waiting for flow2 to complete before resuming flow1, have flow2 send a message to a new flow3 that handles that portion of the logic, passing all necessary context along through the entire pipeline
l
@Casey Brooks it is more complicated. Flow2 listen to a bluetooh socket until flow1 is getting canceled (
transformWhile
) while flow1 sends data to the bluetooth socket. It is like ping pong...flow1 send request, flow2 listen to response and every successful request needs to be confirmed by receiving an Acknowledgement byte. flow1 has to wait for this confirmation. I can merge the code together but then I have requesting and receiving logic tightly coupled and that does not representing my current implementation which decouples both in a clean way
p
You can just loop it if I understand correctly? I.e. while true f1.first() f2.first()
n
Sounds like you may want something like:
Copy code
coroutineScope {
    val channel2 = flow2.produceIn(this)
    try {
        flow1.collectWhile {
            sendRequest(it)
            handleResponse(channel2.receiveCatching())
        }
    } finally {
        channel2.close()
    }
}
j
first() is a terminator operator I think, the flow would end when you call it