仅返回更快协程的值

时间:2019-07-11 11:05:41

标签: kotlin kotlin-coroutines

如何并行运行多个协程并仅返回最先完成的协程的值?

在现实生活中,我有两个数据源-数据库 API服务。我不在乎数据从哪里来,我只需要快速。我该如何查询数据库 API服务并在另一个请求结束时取消另一个请求?

在RxJava世界中,该值等于Amb operator。如何使用协程实现类似的行为?

2 个答案:

答案 0 :(得分:1)

您可以使用select编写自己的amb运算符。像这样:

suspend fun <T> amb(vararg jobs: Deferred<T>): T = select {
    fun cancelAll() = jobs.forEach { it.cancel() }

    for (deferred in jobs) {
        deferred.onAwait {
            cancelAll()
            it
        }
    }
}

您可以详细了解select表达式here

答案 1 :(得分:1)

我想出了以下实施方案:

suspend fun getFaster(): Int = coroutineScope {
    select<Int> {
        async { getFromServer() }.onAwait { it }
        async { getFromDB() }.onAwait { it }
    }.also {
        coroutineContext.cancelChildren()
    }
}

coroutineScope充当其中执行的所有异步调用的父级。 select完成后,我们可以取消其余部分。