结合kotlin流动结果

结合kotlin流动结果,kotlin,concurrency,kotlin-coroutines,kotlin-flow,Kotlin,Concurrency,Kotlin Coroutines,Kotlin Flow,我想知道是否有一种干净的方法可以在Kotlin中启动一系列流,然后在它们解决后,根据它们是否成功执行进一步的操作 例如,我需要从DB读取所有整数(将它们返回到流中),对照外部API检查它们是偶数还是奇数(也返回流),然后从DB中删除奇数 在代码中是这样的 fun findEven(){ db.readIntegers() .map{listOfInt-> listOfInt.asFlow() .flatMapMerge{singleInt-> httpClient.apicalltocheckf

我想知道是否有一种干净的方法可以在Kotlin中启动一系列流,然后在它们解决后,根据它们是否成功执行进一步的操作

例如,我需要从DB读取所有整数(将它们返回到流中),对照外部API检查它们是偶数还是奇数(也返回流),然后从DB中删除奇数

在代码中是这样的

fun findEven(){
db.readIntegers()
.map{listOfInt->
listOfInt.asFlow()
.flatMapMerge{singleInt->
httpClient.apicalltocheckforodity(singleInt)
.接住{
//当数字为偶数时API失败
}
.地图{
//当数字为奇数时API成功
db.remove(singleInt.collect())
}
}.collect()
}.collect()
}

但我看到这段代码的问题是访问DB删除条目是并行的,我认为更好的解决方案是运行所有API调用并在某个地方收集所有失败和成功的,因此,为了能够在数据库中只执行一次批量插入,而不是让多个协同程序自己执行该操作,我认为,在
映射
过滤器等中产生副作用是一种反模式。副作用(如从数据库中删除项)应该是一个单独的步骤(
collect
在流的情况下,以及
forEach
在列表的情况下)为了清晰起见

嵌套流也有点复杂,因为您可以直接将列表修改为列表

我认为您可以这样做,假设API一次只能检查一项

suspend fun findEven() {
    db.readIntegers()
            .map { listOfInt ->
                listOfInt.filter { singleInt ->
                    runCatching {
                        httpClient.apiCallToCheckForOddity(singleInt)
                    }.isSuccess
                }
            }
            .collect { listOfOddInt ->
                db.removeAll(listOfOddInt)
            }
}
并行版本,如果API调用返回参数。()

suspend fun findEven(){
db.readIntegers()
.map{listOfInt->
共线镜{
listOfInt.map{singleInt->
异步的{
奔跑{
httpClient.apicalltocheckforodity(singleInt)
}
}
}.all()
.mapNotNull(结果::getOrNull)
}
}
.collect{listofaddint->
db.removeAll(列表添加)
}
}

在我看来,在
地图
过滤器
等中产生副作用是一种反模式。为了清晰起见,从数据库中删除项目等副作用应该是一个单独的步骤(
在流中收集
,在列表中为每个

嵌套流也有点复杂,因为您可以直接将列表修改为列表

我认为您可以这样做,假设API一次只能检查一项

suspend fun findEven() {
    db.readIntegers()
            .map { listOfInt ->
                listOfInt.filter { singleInt ->
                    runCatching {
                        httpClient.apiCallToCheckForOddity(singleInt)
                    }.isSuccess
                }
            }
            .collect { listOfOddInt ->
                db.removeAll(listOfOddInt)
            }
}
并行版本,如果API调用返回参数。()

suspend fun findEven(){
db.readIntegers()
.map{listOfInt->
共线镜{
listOfInt.map{singleInt->
异步的{
奔跑{
httpClient.apicalltocheckforodity(singleInt)
}
}
}.all()
.mapNotNull(结果::getOrNull)
}
}
.collect{listofaddint->
db.removeAll(列表添加)
}
}

readIntegers返回什么?
Flow
?是的(我试图用闭包中给出的名称指定它)readIntegers返回什么?
Flow
?是的(我试图用闭包中给出的名称指定它)谢谢,回答得很好。我不知道runCatching及其isSuccess和isFailure。是的,对于API,我只是将其设置为(可能不好)举个例子,但我绝对不是针对这样的东西。谢谢,回答得很好。我不知道runCatching及其isSuccess和isFailure。是的,对于API,我只是把它作为一个例子(可能是不好的),但我绝对不是针对这样的东西。