RxJava2 - объединение нескольких синглов, отправленных результатов в карту - PullRequest
0 голосов
/ 11 декабря 2018

Я получаю List<User> с сервера.

class User {
  Long localId;
  String remoteId;
  ..
}

Мне нужно вставить каждого пользователя из списка в локальную базу данных и вконец получает HashMap<String,Long> (объект, который отображает remoteId на localId)

Каждый insertToLocalDb возвращает Single<Long>.Таким образом, Observable испускает вставленные User localId

Как мне добиться этого реактивным способом?

1 Ответ

0 голосов
/ 11 декабря 2018

Прежде всего, я должен предложить использовать транзакцию для нескольких операций с БД, как в вашем случае.

Тривиальное неэффективное решение может выглядеть так:

fetchUsers()
  .flatMap { users ->
        Observable.fromIterable(users)
            .flatMapSingle { user -> dao.save(user) }
            .toList()
            .map { databaseIds ->
                val remoteIds = users.map { it.remoteId }
                databaseIds.zip(remoteIds).toMap()
            }

Нопринимая во внимание транзакцию, Room поддерживает это, например, это может выглядеть следующим образом:

fetchUsers().flatMap { users ->
        dao.saveAll(users) // typically returns Single<List<Long>>
            .map { databaseIds ->
                val remoteIds = users.map { it.remoteId }
                databaseIds.zip(remoteIds).toMap()
            }
    }

Оба приведут к Single<Map<String, Long>>, но второй подход гораздо более производительный, если вы используетесделка.

...