通过 Kotlin Coroutine Flow 压缩网络请求

Posted

技术标签:

【中文标题】通过 Kotlin Coroutine Flow 压缩网络请求【英文标题】:Zip network requests via Kotlin Coroutine Flow 【发布时间】:2019-10-30 12:49:25 【问题描述】:

我有一个通过 RxJava 压缩两个网络请求的代码:

Single.zip(repository.requestDate(), repository.requestTime()) 
  date, time -> Result(date, time)

表示repository.requestDate()/repository.requestTime()返回Single<T>

如果我想使用协程,我需要将请求更改为:

@GET('link/date')
suspend fun requestDate() : Date

@GET('link/time')
suspend fun requestTime() : Time

但是,如何通过来自 Kotlin Coroutines 的 Flow 压缩请求?

我知道我可以这样做:

coroutineScope 
   val date = repository.requestDate()
   val time = repository.requestTime()
   Result(date, time)

但我想通过 Flow 来实现!

我知道 Channels,但 Channels.zip() 已被弃用。

【问题讨论】:

【参考方案1】:
val dateFlow = flowOf(repository.requestDate())
val timeFlow = flowOf(repository.requestTime())
val zippedFlow = dateFlow.zip(timeFlow)  date, time -> Result(date, time) 

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/zip.html

【讨论】:

【参考方案2】:

对于大多数操作Flow 遵循与普通协程相同的规则,因此要压缩两个单独的请求,您需要应用async concurrency pattern。

实际上,这最终会是这样的:

flow 
    emit(coroutineScope/withContext(SomeDispatcher) 
        val date = async  repository.requestDate() 
        val time = async  repository.requestTime() 
        Result(date.await(), time.await())
    )

【讨论】:

感谢您的回答。我认为 Flow Coroutines 可以取代流行的 RX 操作符,但它看起来并不简洁。也许,最好使用 Channels 来完成任务?你觉得怎么样? @kiskae 这里的“结果”是什么? 代码是OPs原RxJava代码的直接翻译,所以是OP提供的一个类。

以上是关于通过 Kotlin Coroutine Flow 压缩网络请求的主要内容,如果未能解决你的问题,请参考以下文章

kotlin - Coroutine 协程

Kotlin 协程单元测试错误:线程“main @coroutine#1 @coroutine#2”中的异常 java.lang.NullPointerException

Kotlin 协程Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 )

Kotlin 协程Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 )

Kotlin 协程Flow 异步流 ⑥ ( 调用 Flow#launchIn 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )

Kotlin 协程Flow 异步流 ⑥ ( 调用 Flow#launchIn 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )