如何从 kotlin coroutines Deferred<>(服务器)中找到第一个想要的结果
How to find first desired result from kotlin coroutines Deferred<> (server)
我已经构建了一个分片库,我正在尝试向其中添加协程功能。在以下代码片段中,它 return 是它找到的第一个 true
结果:
override fun emailExists(email: String): Boolean {
return runBlocking {
shards
.asyncAll { userDao.emailExists(email) }
.map { it.await() }
.firstOrNull { it }
} ?: false
}
shards.asyncAll方法是:
fun <T> async(
shardId: Long,
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T): Deferred<T> {
return scope.async(context, start) {
selectShard(shardId)
block()
}
}
fun <T> asyncAll(
shardIds: Collection<Long> = this.shardIds,
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T): List<Deferred<T>> {
return shardIds.map { async(it, context, start, block) }
}
这行得通,但它会按照 return 的顺序查询分片,这意味着如果第一个分片需要很长时间才能 return 而它不会 return true
但第二个分片 return 的值立即变为 true
我们仍在等待,只要第一个分片达到 return。有没有更好的方法来等待 Deferred<>
集合的值并按照它们 return 的顺序处理它们,以便我可以尽早退出?
即使您提前得到答案,runBlocking
仍会等待您开始的所有协程完成后再返回。
为了 运行 您正在寻找的那种协程竞赛:
- 当第一个任务完成 true 时,它需要存储该结果并取消所有其他任务的父作业;和
- 其他任务在取消时应该正确中止。
不幸的是,我很确定 Kotlin 不包含执行此操作的函数,因此您必须自己完成。最简单的方法可能是让每个都抛出一个异常来指示真实结果。然后,您可以在该组上使用 awaitAll
,捕获异常并提取结果。
我已经构建了一个分片库,我正在尝试向其中添加协程功能。在以下代码片段中,它 return 是它找到的第一个 true
结果:
override fun emailExists(email: String): Boolean {
return runBlocking {
shards
.asyncAll { userDao.emailExists(email) }
.map { it.await() }
.firstOrNull { it }
} ?: false
}
shards.asyncAll方法是:
fun <T> async(
shardId: Long,
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T): Deferred<T> {
return scope.async(context, start) {
selectShard(shardId)
block()
}
}
fun <T> asyncAll(
shardIds: Collection<Long> = this.shardIds,
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T): List<Deferred<T>> {
return shardIds.map { async(it, context, start, block) }
}
这行得通,但它会按照 return 的顺序查询分片,这意味着如果第一个分片需要很长时间才能 return 而它不会 return true
但第二个分片 return 的值立即变为 true
我们仍在等待,只要第一个分片达到 return。有没有更好的方法来等待 Deferred<>
集合的值并按照它们 return 的顺序处理它们,以便我可以尽早退出?
即使您提前得到答案,runBlocking
仍会等待您开始的所有协程完成后再返回。
为了 运行 您正在寻找的那种协程竞赛:
- 当第一个任务完成 true 时,它需要存储该结果并取消所有其他任务的父作业;和
- 其他任务在取消时应该正确中止。
不幸的是,我很确定 Kotlin 不包含执行此操作的函数,因此您必须自己完成。最简单的方法可能是让每个都抛出一个异常来指示真实结果。然后,您可以在该组上使用 awaitAll
,捕获异常并提取结果。