首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin延迟的anyOf等价

Kotlin延迟的anyOf等价
EN

Stack Overflow用户
提问于 2018-03-29 18:01:47
回答 3查看 704关注 0票数 10

协程async返回Deferred<T>,并且有延迟执行的示例和await的用法。

但是,我们如何等待任何一个Deffered实例完成呢?

简而言之

代码语言:javascript
复制
  // whats the equivalent of CompletableFuture.anyOf(...)?
  // is this how we do it? if so how costly is this?
  select<Unit> {
     deffered1.onAwait {}
     deffered2.onAwait {}
  }
EN

回答 3

Stack Overflow用户

发布于 2018-04-07 07:01:58

可能不是最安全的方法,但这样的方法应该可以工作:

代码语言:javascript
复制
inline suspend fun <T> Iterable<Deferred<T>>.awaitAny(): T {
    var completed: T? = null
    forEachIndexed { index, deferred ->
        deferred.invokeOnCompletion {
            completed = deferred.getCompleted()
            forEachIndexed { index2, deferred2 ->
                if (index != index2) {
                    deferred2.cancel(it)
                }
            }
        }
    }
    forEach {
        try {
            it.await()
        } catch (ignored: JobCancellationException) {
            // ignore
        }
    }
    return completed!!
}

打样:下面打印1000张

代码语言:javascript
复制
launch(CommonPool) {
        // 10 - 1 second(s)
        val deferredInts = List(10, {
            val delayMs = (10 - it) * 1000
            async(CommonPool) {
                delay(delayMs)
                delayMs
            }
        })
        val first = deferredInts.awaitAny()
        println(first)
    }
票数 2
EN

Stack Overflow用户

发布于 2018-12-30 19:00:17

使用如下select表达式

代码语言:javascript
复制
        val deferred1: Deferred<String?> = GlobalScope.async { getValue1() }
        val deferred2: Deferred<String?> = GlobalScope.async { getValue2() }
        val deferred3: Deferred<String?> = GlobalScope.async { getValue3() }

        val deferredList = listOf(deferred1, deferred2, deferred3)
        val firstCompletedResult = select<String?> {
            deferredList.forEach {
                it.onAwait {}
            }
        }
        
        Log.d(TAG, "firstCompleted: $firstCompletedResult")
票数 2
EN

Stack Overflow用户

发布于 2021-05-27 23:00:13

对于多样性,提到select().merge(): Flow替代方案,我用它来处理a similar problem (获取延迟集合中的第一个,以非空值完成),即

代码语言:javascript
复制
val firstCompletedResult = deferreds.map { it::await.asFlow() }.merge().first()

或者如果你喜欢的话

代码语言:javascript
复制
suspend fun <T> Iterable<Deferred<T>>.awaitAny(): T = map { it::await.asFlow() }.merge().first()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49553213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档