mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-11-26 03:58:45 +00:00
awaitFirst
This commit is contained in:
parent
9acb9af338
commit
a3087cb650
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## 0.4.18
|
## 0.4.18
|
||||||
|
|
||||||
|
* `Coroutines`:
|
||||||
|
* New extension `Iterable<Deferred>#awaitFirst` has been added
|
||||||
* `Serialization`
|
* `Serialization`
|
||||||
* `Base 64`
|
* `Base 64`
|
||||||
* New `Base64ByteArraySerializer` has been added
|
* New `Base64ByteArraySerializer` has been added
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
|
||||||
|
suspend fun <T> Iterable<Deferred<T>>.awaitFirst(
|
||||||
|
scope: CoroutineScope,
|
||||||
|
cancelOnResult: Boolean = true
|
||||||
|
): T = suspendCoroutine<T> { continuation ->
|
||||||
|
scope.launch(SupervisorJob()) {
|
||||||
|
val scope = this
|
||||||
|
forEach {
|
||||||
|
scope.launch {
|
||||||
|
continuation.resume(it.await())
|
||||||
|
scope.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.also {
|
||||||
|
if (cancelOnResult) {
|
||||||
|
forEach {
|
||||||
|
try {
|
||||||
|
it.cancel()
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
suspend fun <T> Iterable<Deferred<T>>.awaitFirst(
|
||||||
|
cancelOthers: Boolean = true
|
||||||
|
): T = awaitFirst(CoroutineScope(coroutineContext), cancelOthers)
|
@ -0,0 +1,34 @@
|
|||||||
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class AwaitFirstTests {
|
||||||
|
private fun CoroutineScope.createTestDeferred(value: Int, wait: Long = 100000) = async(start = CoroutineStart.LAZY) { delay(wait); value }
|
||||||
|
@Test
|
||||||
|
fun testThatAwaitFirstIsWorkingCorrectly() {
|
||||||
|
val baseScope = CoroutineScope(Dispatchers.Default)
|
||||||
|
val resultDeferred = baseScope.createTestDeferred(-1, 0)
|
||||||
|
val deferreds = listOf(
|
||||||
|
baseScope.async { createTestDeferred(0) },
|
||||||
|
baseScope.async { createTestDeferred(1) },
|
||||||
|
baseScope.async { createTestDeferred(2) },
|
||||||
|
resultDeferred
|
||||||
|
)
|
||||||
|
val controlJob = baseScope.launch {
|
||||||
|
delay(1000000)
|
||||||
|
}
|
||||||
|
val result = baseScope.launchSynchronously {
|
||||||
|
val result = deferreds.awaitFirst(baseScope)
|
||||||
|
|
||||||
|
assertTrue(baseScope.isActive)
|
||||||
|
assertTrue(controlJob.isActive)
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
assertEquals(baseScope.launchSynchronously { resultDeferred.await() }, result)
|
||||||
|
assertTrue(deferreds.all { it == resultDeferred || it.isCancelled })
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user