使用Kotlin协程加载多个JPA实体

时间:2018-12-21 22:52:51

标签: hibernate kotlin kotlinx.coroutines

我正在尝试在应用程序层中使用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,但我在任何地方都找不到它的任何示例。能做到吗?

3 个答案:

答案 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()
}