首页 > 解决方案 > 带有可选异步依赖项的 Kotlin 异步处理

问题描述

我有一个有条件地获取一些数据并在该数据上同时运行一些任务的函数。每个任务取决于不同的数据集,我想避免获取不需要的数据。此外,一些数据可能已经被预取并提供给函数。请参阅下面我提出的代码。

suspend fun process(input: SomeInput, prefetchedDataX: DataX?, prefetchedDataY: DataY?) = coroutineScope {
   val dataXAsync = lazy {
       if (prefetchedDataX == null) {
           async { fetchDataX(input) }
       } else CompletableDeferred(prefetchedDataX)
   }

   val dataYAsync = lazy {
       if (prefetchedDataY == null) {
           async { fetchDataY(input) }
       } else CompletableDeferred(prefetchedDataY)
   }

   if (shouldDoOne(input)) launch {
     val (dataX, dataY) = awaitAll(dataXAsync.value, dataYAsync.value)
     val modifiedDataX = modifyX(dataX)
     val modifiedDataY = modifyY(dataY)
     doOne(modifiedDataX, modifiedDataY)
   }

   if (shouldDoTwo(input)) launch {
     val modifiedDataX = modifyX(dataXAsync.value.await())
     doTwo(modifiedDataX)
   }

   if (shouldDoThree(input)) launch {
     val modifiedDataY = modifyY(dataYAsync.value.await())
     doThree(modifiedDataY)
   }

}

可以对此代码进行任何改进吗?一,我不喜欢将预取的数据伪装成一个CompletableDeferred. 第二,我不喜欢在每个任务中调用modifyXmodifyY我希望我可以在获取阶段应用它,但我还没有想出一个好的方法来做到这一点。或者我可以做

val modifiedDataXAsync = lazy {
   async { modifyX(prefetchedDataX ?: fetchDataX(input)) } 
}

但是当数据已经预取时产生一个新的协程感觉很浪费。我是否过度优化?

标签: kotlinkotlin-coroutines

解决方案


这个怎么样?这段代码和你的很相似,我只是简化了一点。

suspend fun process(input: SomeInput, prefetchedDataX: DataX?, prefetchedDataY: DataY?) = coroutineScope {

   val modifiedDataX by lazy {
       async { modifyX(prefetchedDataX ?: fetchDataX(input)) }
   }

   val modifiedDataY by lazy {
       async { modifyY(prefetchedDataY ?: fetchDataY(input)) }
   }

   if (shouldDoOne(input)) launch {
       val (dataX, dataY) = awaitAll(modifiedDataX, modifiedDataY)
       doOne(dataX, dataY)
   }

   if (shouldDoTwo(input)) launch {
       doTwo(modifiedDataX.await())
   }

   if (shouldDoThree(input)) launch {
       doThree(modifiedDataY.await())
   }
}

推荐阅读