具有可选异步依赖项的Kotlin异步处理

时间:2020-06-13 02:23:46

标签: kotlin kotlin-coroutines

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

C:\Users\HP\Desktop\DiscordBot\index.js:12
        message.member.addRole(Blue);
                       ^

TypeError: message.member.addRole is not a function
    at Client.<anonymous> (C:\Users\HP\Desktop\DiscordBot\index.js:12:24)
    at Client.emit (events.js:315:20)
    at MessageCreateAction.handle (C:\Users\HP\Desktop\DiscordBot\node_modules\discord.js\src\client\actions\MessageCreate.js:31:14)
    at Object.module.exports [as MESSAGE_CREATE] (C:\Users\HP\Desktop\DiscordBot\node_modules\discord.js\src\client\websocket\handlers\MESSAGE_CREATE.js:4:32)
    at WebSocketManager.handlePacket (C:\Users\HP\Desktop\DiscordBot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:386:31)
    at WebSocketShard.onPacket (C:\Users\HP\Desktop\DiscordBot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:436:22)
    at WebSocketShard.onMessage (C:\Users\HP\Desktop\DiscordBot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:293:10)
    at WebSocket.onMessage (C:\Users\HP\Desktop\DiscordBot\node_modules\ws\lib\event-target.js:125:16)
    at WebSocket.emit (events.js:315:20)
    at Receiver.receiverOnMessage (C:\Users\HP\Desktop\DiscordBot\node_modules\ws\lib\websocket.js:800:20)

可以对此代码进行任何改进吗?第一,我不希望将伪造的数据伪装到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) } } 中。第二,我不想在每个任务中都调用CompletableDeferredmodifyX,但愿在获取阶段应用它,但是我并没有想办法。或者,我可以做

modifyY

,但是在已经预取数据时生成一个新的协程是很浪费的。我过度优化了吗?

1 个答案:

答案 0 :(得分:1)

这个怎么样?这段代码与您的代码非常相似,我只是对其进行了简化。

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