我正在尝试在循环中创建一些协程(异步)。我想并行开始所有事情,然后等待它们全部完成然后再继续。 documentation提供以下示例:
coroutineScope {
val deferreds = listOf( // fetch two docs at the same time
async { fetchDoc(1) }, // async returns a result for the first doc
async { fetchDoc(2) } // async returns a result for the second doc
deferreds.awaitAll() // use awaitAll to wait for both network requests
}
但这要求提前知道所有类实例化。然而,对于不同数量的实例,这是不切实际的。作为解决方法,我发现以下方法有效:
给定 MyObject
类中的类对象的可变列表,并且 MyObject
有一个名为 myDo()
private val mObjects = mutableListOf<MyObject>()
并忽略错误检查并假设列表有 2 个或更多对象,则以下内容可以工作,但有点笨拙且不太优雅
coroutineScope {
val pd = async { myObjects[0].myDo() }
val dds = mutableListOf(pd)
for (i in 1..numObjects - 1) {
dds.add(async {mObjects[i].myDo() })
}
val nds = dds.toList()
nds.awaitAll()
}// end coroutineScope
我希望做的事情是这样的
val dds = mutableListOf<Job>()
for (i in 0..numObjects - 1) {
dds.add(async {mObjects[i].myDo() })
}
val nds = dds.toList()
nds.awaitAll()
但这不起作用,因为异步结果是
Deferred<out T> : Job
接口(interface)不是作业接口(interface)。问题就出在这行
val dds = mutableListOf<Job>()
我不知道用什么来代替 Job。也就是说,对于异步来说,T 是什么?
如有任何帮助或建议,我们将不胜感激
最佳答案
T
在这种情况下是任何类型 myDo()
返回。
我认为您通过创建额外的 MutableLists 使事情变得过于复杂。你可以这样做:
val results = coroutineScope {
mObjects.map { obj ->
async { obj.myDo() }
}.awaitAll()
}
results
将是 List<MyDoReturnType>
.
编辑:我刚刚意识到,因为您并不明显知道 Deferred 的类型是什么 async
lambda 返回,也许是因为 myDo()
不返回任何内容(隐式返回单位)。如果是这种情况,您应该使用 launch
而不是async
。它们之间唯一的区别是async
的 lambda 返回一些内容并且 launch
的没有。 Deferred 继承自 Job,因为 Deferred 是一个有结果的 Job。如果myDo()
不返回任何内容,您的代码应如下所示,没有结果。
coroutineScope {
for (obj in mObjects) launch { obj.myDo() }
}
关于android - 异步结果的类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70869512/