我正在尝试在应用程序层中使用Hibernate和Kotlin协程加载多个实体。做这样的事情。
fun load() : SomeData {
val steps = someFunctionCallToGetSteps()
val stepCollection : List<Step> = MutableList()
runBlocking {
for (step in steps) {
val s = async { getStepData(step) }
payers.add(s.await())
}
}
}
private suspend fun getStepData(step : Int) : Iterable<Step> {
return someComputation()
}
但是这种方法是不正确的,因为我立即使用了await
,所以它每次都不同步。我被告知要收集所有延期并使用awaitAll
,但我在任何地方都找不到它的任何示例。能做到吗?
答案 0 :(得分:0)
将每个s
放入列表,并在for循环之外进行awaitAll(yourListOfs)
答案 1 :(得分:0)
如果我做对了,您需要类似的东西来实现您的目标。呼叫多个async
建设者,然后将Deferred
映射到Step
。宁愿使用Dispatchers.Default
,也最好使用create your own dispatcher。
data class Step(val step: Int)
fun main(args: Array<String>) = runBlocking {
val steps = someFunctionCallToGetSteps()
val result = coroutineScope {
val defferedSteps = steps.map {
async(Dispatchers.Default) {
getStepData(it)
}
}
defferedSteps.map { deferred -> deferred.await() }
}
for (step in result)
println(step)
}
fun someFunctionCallToGetSteps(): List<Int> {
return listOf<Int>(1, 2, 3, 4)
}
suspend fun getStepData(step: Int): Step {
println("[${Thread.currentThread().name}] loading...")
delay(500)
return Step(step)
}
答案 2 :(得分:0)
最后,我能够解决此问题。我正在发布答案,希望其他人可以从中受益。
fun load() : List<Result> {
val steps = someFunctionCallToGetSteps()
val result: List<Result> = ...
runBlocking {
val stepsDeferred = steps.map { async { getStepData(it) } }
stepsDeferred.awaitAll().forEach { result.add(it) }
}
return result
}
private suspend fun getStepData(step : Int) : Iterable<Step> {
return someComputation()
}