Лучший способ запустить код после вызова emitAll - PullRequest
0 голосов
/ 13 июля 2020

Я использую LocalDataSource как единственный источник истины, а RemoteDataSource используется для его актуализации.

Поскольку emitAll() и Flow.collect() блокируются, я сначала получаю последнее кешированное значение , Я загружаю последнее значение из RemoteDataSource, вставляю их локально и, наконец, я снова начал слушать LocalDatasource.

Текущее решение:

override fun getById(venueId: String) = flow {
    emit(localDataSource.getById(venueId).first())

    val remoteVenue = remoteDataSource.getById(venueId)
    localDataSource.mergeOrInsert(remoteVenue)

    emitAll(localDataSource.getById(venueId).filterNotNull())
}

Можно ли это сделать по-другому , без явного извлечения последнего кешированного значения? Можно ли это сделать, сразу послушав LocalDataSource и потом вставив скачанное обновление? Основная цель - сделать код максимально ясным. Использование каналов могло бы быть решением, но это, вероятно, отклоняется от цели добавления ясности.

Итак, нерабочий пример A, примерно так:

override fun getById(venueId: String) = flow {
    nonBlockingEmitAll(localDataSource.getById(venueId))

    val remoteVenue = remoteDataSource.getById(venueId)
    localDataSource.mergeOrInsert(remoteVenue)
}

Или рабочий пример B :,

override fun getById(venueId: String) = flow {
    CoroutineScope(coroutineContext).launch {
        val remoteVenue = wrapCall { remoteDataSource.getById(venueId) }
        remoteVenue?.let { localDataSource.mergeOrInsert(it) }
    }

    emitAll(localDataSource.getById(venueId))
}

В примере B вызов ограничен в рамках потока и не будет протекать, но, возможно, создание CoroutineScope слишком сложно?

Какой из этих 3 блоков кода лучше ? Есть ли еще лучшее решение?

...