在内部等待或如何获得父范围?科特林

时间:2020-04-27 16:37:23

标签: kotlin kotlin-coroutines

我有一个功能:

suspend fun getChats() {
    val chatList = mutableListOf<Chat>()
    getMyChats { chats ->
        chats.forEach {
            it.getDetail().await()
        }
    }.await()
}

但是编译器在Suspension functions can be called only within coroutine body循环内显示await()的{​​{1}}。如何避免此问题或如何为其传递父级作用域?

** getMyChats()收到回调

2 个答案:

答案 0 :(得分:1)

根据您的说法,getMyChats不支持采用可挂起的代码块(lambda)。

因此您可以用suspendCancellableCoroutine包裹它。

suspend fun getMyChatsSuspend(): List<Chat> = suspendCancellableCoroutine { cont ->
    getMyChats { cont.resume(it) }
}

现在像这样使用您的函数:

suspend fun getChats() {
    ...
    val chats = getMyChatsSuspend()
    val chatDetails = chats.map{ chat.getDetail() }
    val chatDetailsAwait = awaitAll( *chatDetails.toTypedArray() )
}

很明显,只是链接调用而不是根据需要创建多个变量

如果您希望所有事情都在一行中完成,则可以执行以下操作:

val resolvedDetails = getMyChatsSuspend().map{ chat.getDetail() }.let { awaitAll(*it.toTypedArray()) }

答案 1 :(得分:1)

您必须像@Animesh Sahu所说的那样隔离getMyChats函数,但是对await()的最后一次调用看起来非常可疑,因此我将其重写。 我还将假设await不一定在Deferred<T>上。

suspend fun getChats() {
    val chatList = mutableListOf<Chat>()

    val result = CompletableDeferred<List<Chat>>()
    getMyChats { result.complete(it) }.await()
    val chats = result.await()
    chats.forEach {
        it.getDetail().await()
    }
}

如果您提供所涉及功能的功能签名,我也许可以为您提供更好的解决方案。 尽管不讨论其他内容,但我可以告诉您getMyChats函数需要重构。