Issue
I am developing a Kotlin Android application In my app, I need to run multiple coroutines in parallel and I would like to return only the first not null value of the one that finishes first?
I used the select expression, sample found there: https://kotlinlang.org/docs/select-expression.html#selecting-deferred-values
import kotlinx.coroutines.*
import kotlinx.coroutines.selects.*
import java.util.*
fun CoroutineScope.asyncString(time: Int) = async {
delay(time.toLong())
null
}
fun CoroutineScope.asyncStringsList(): List<Deferred<String>> {
val random = Random(3)
return List(12) { asyncString(random.nextInt(1000)) }
}
fun main() = runBlocking<Unit> {
val list = asyncStringsList()
val result = select<String> {
list.withIndex().forEach { (index, deferred) ->
deferred.onAwait { answer ->
answer
}
}
}
println(result)
}
In my case, it would be :
list.withIndex().forEach { (index, deferred) ->
deferred.onAwait { answer ->
if (answer == null) return else answer
}
}
but I have this error: 'return' is not allowed here.
Any suggestions ?
Thanks
Solution
I haven't done much with select clauses, and I don't know how to selectively pick whether to reject a result and wait for the next one. (Seems like a critical missing feature.)
Here's a way I think you can do something similar using channelFlow. It launches parallel coroutines for each Deferred and they are emitted by the Flow in order, so you can then filter and pick the first one with first().
fun main() = runBlocking {
val list = asyncStringsList()
val result = channelFlow {
list.forEach { launch { send(it.await()) } }
}
.filterNotNull()
.first()
println(result)
}
Answered By - Tenfour04
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.