摆脱嵌套的任务类型

时间:2019-01-01 22:13:14

标签: android kotlin google-cloud-firestore google-tasks-api

是否有可能摆脱嵌套的Task泛型?

对于每个continueWith语句,在该类型中添加一个新的Task。每个延续都是该类型的一部分。理想情况下,我将返回一个Task,该Task连续执行每个任务,并以一个任务成功或失败。

示例

第一个操作查询用户组

private fun getGroupsSnapshot(): Task<QuerySnapshot> {
    val userId = Auth.currentUser()!!.uid
    val query = userGroupsQuery(groupsCollection, userId)
    return query.get()
}

第二项操作查询这些组中的相册。

fun getAlbums(): Task<Task<List<Album>>> {
    return getGroupsSnapshot().continueWith { task ->
        val documentSnapshots = TaskUtils.getResult(task)
        val albums = mutableListOf<Album>()
        val fetchAlbumTasks = documentSnapshots.documents.map { document ->
            Log.d(TAG, document["name"].toString())
            document.reference.collection("albums").get().addOnCompleteListener { queryTask ->
                albums.addAll(toObjects(Album::class.java, queryTask))
            }
        }
        return@continueWith Tasks.whenAll(fetchAlbumTasks).continueWith allTasks@ {
            return@allTasks albums as List<Album>
        }
    }
}

但是我希望此操作返回类型Task<List<Album>>以保持界面清洁。

1 个答案:

答案 0 :(得分:2)

要组成多个Task,应使用continueWithTask而不是continueWith。它接受一个Continuation<TResult, Task<TContinuationResult>作为参数,这实际上使返回的Task变平并避免嵌套。您应该将其视为Monads中的mapflatMap操作(即List),在这种情况下,如果您使用continueWithTask相当于flatMap使用List作为容器而不是Task(请记住,使用flatMap会将List的每个元素都转换为新的List,并展平{ {1}})