Kotlin 执行顺序和结果问题
Kotlin Execution order and result issues
我正在尝试通过 listAll 从 firebase 的存储中获取所有文件。
顺便说一下..
storageReference.listAll().addOnSuccessListener { listResult ->
val image_task : FileDownloadTask
for (fileRef in listResult.items) {
fileRef.downloadUrl.addOnSuccessListener { Uri ->
image_list.add(Uri.toString())
println("size1 : " + image_list.size)
}
}
println("size2 : " + image_list.size)
}//addOnSuccessListener
enter image description here
为什么执行顺序是这样的?
我该如何解决??
这里的执行顺序没有错
fileRef.downloadUrl.addOnSuccessListener { Uri ->
downloadUrl
是一个异步操作,这意味着它不会等待操作实际完成才能与代码一起移动。
您会收到成功侦听器的结果(至少在这种情况下)
如果要按顺序处理,看coroutines.
当您为某物添加监听器或回调时,监听器中的代码直到稍后才会被调用。当前函数中的所有其他内容将首先发生。
您正在使用 for 循环为每个项目添加侦听器。监听器中还没有代码 运行。然后你的 "size2" println
调用是在 for 循环之后进行的。稍后,您所有的听众都会开火。
如果你想像这样的异步代码是顺序写的,那你就需要用到协程。这是一个很大的话题,但您的代码看起来像这样(但如果您想正确处理错误,可能会比这更复杂)。对于此示例,我使用 Android Activity 或 Fragment 中的 lifecycleScope
。如果你不在 Android,你需要使用一些其他的 CoroutineScope。
调用 await()
是添加成功和失败侦听器的替代方法。 await()
挂起协同程序,然后 returns 返回结果或在失败时抛出异常。
lifecycleScope.launch {
val results = try {
storageReference.listAll().await()
} catch (e: Exception) {
println("Failed to get list: ${e.message}")
return@launch
}
val uris = try {
results.map { it.downloadUrl.await().toString() }
} catch (e: Exception) {
println("Failed to get at least one URI: ${e.message}")
return@launch
}
image_list.addAll(uris)
}
我正在尝试通过 listAll 从 firebase 的存储中获取所有文件。
顺便说一下..
storageReference.listAll().addOnSuccessListener { listResult ->
val image_task : FileDownloadTask
for (fileRef in listResult.items) {
fileRef.downloadUrl.addOnSuccessListener { Uri ->
image_list.add(Uri.toString())
println("size1 : " + image_list.size)
}
}
println("size2 : " + image_list.size)
}//addOnSuccessListener
enter image description here
为什么执行顺序是这样的?
我该如何解决??
这里的执行顺序没有错
fileRef.downloadUrl.addOnSuccessListener { Uri ->
downloadUrl
是一个异步操作,这意味着它不会等待操作实际完成才能与代码一起移动。
您会收到成功侦听器的结果(至少在这种情况下) 如果要按顺序处理,看coroutines.
当您为某物添加监听器或回调时,监听器中的代码直到稍后才会被调用。当前函数中的所有其他内容将首先发生。
您正在使用 for 循环为每个项目添加侦听器。监听器中还没有代码 运行。然后你的 "size2" println
调用是在 for 循环之后进行的。稍后,您所有的听众都会开火。
如果你想像这样的异步代码是顺序写的,那你就需要用到协程。这是一个很大的话题,但您的代码看起来像这样(但如果您想正确处理错误,可能会比这更复杂)。对于此示例,我使用 Android Activity 或 Fragment 中的 lifecycleScope
。如果你不在 Android,你需要使用一些其他的 CoroutineScope。
调用 await()
是添加成功和失败侦听器的替代方法。 await()
挂起协同程序,然后 returns 返回结果或在失败时抛出异常。
lifecycleScope.launch {
val results = try {
storageReference.listAll().await()
} catch (e: Exception) {
println("Failed to get list: ${e.message}")
return@launch
}
val uris = try {
results.map { it.downloadUrl.await().toString() }
} catch (e: Exception) {
println("Failed to get at least one URI: ${e.message}")
return@launch
}
image_list.addAll(uris)
}