【问题标题】:Load several JPA entities using Kotlin coroutine使用 Kotlin 协程加载多个 JPA 实体
【发布时间】:2018-12-21 22:52:51
【问题描述】:

我正在尝试在应用层中使用 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,但我在任何地方都找不到任何例子。这个可以吗?

【问题讨论】:

    标签: hibernate kotlin kotlinx.coroutines


    【解决方案1】:

    将每个s 放入一个列表并在for 循环之外执行awaitAll(yourListOfs)

    【讨论】:

    • 那么我该如何将结果再次添加到列表中呢?
    • 我做了这个 val s : MutableList>> = mutableListOf() 并添加了所有的 defreds 但是当我做了 d : Iterable = awaitAll(s) 我得到一个错误。
    • 什么样的错误?你不觉得值得一提吗?
    【解决方案2】:

    如果我做对了,你需要这样的东西来实现你的目标。调用多个async 构建器,然后将Deferred 映射到Steps。与其使用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)
    }
    

    【讨论】:

      【解决方案3】:

      我终于能够解决这个问题。我正在发布答案,希望其他人可以从中受益。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        相关资源
        最近更新 更多