Избавление от вложенного типа задачи - PullRequest
0 голосов
/ 02 января 2019

Можно ли избавиться от вложенных обобщений задач?

Для каждого оператора continueWith в тип добавляется новый 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 голосов
/ 02 января 2019

Для составления нескольких Task вы должны использовать continueWithTask вместо continueWith.Он принимает Continuation<TResult, Task<TContinuationResult> в качестве параметра, который по существу выравнивает возвращаемое Task и избегает вложения.Вы должны думать об этом как о map против flatMap операции в Монадах (то есть List), в этом случае continueWithTask будет эквивалентно flatMap, если вы используете List в качестве контейнера вместо Task (Помните, с помощью flatMap вы преобразуете каждый элемент List в новый List и сглаживаете результирующее List)

...