我有一个功能:
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()收到回调
答案 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
函数需要重构。