Как связать Coroutine Flow?

Я мог бы легко связать coroutine Flows, выполнив:

val someFlow = flow { //Some logic that my succeed or throw error }
val anotherFlow = flow { // Another logic that my succeed or throe error }

val resultingFlow = someFlow.flatmapLatest(anotherFlow)

но что, если я хочу индивидуально иметь возможность повторить попытку someFlow а также anotherFlow где если someFlow уже удалось вернуть значение, но anotherFlow не удалось, я хочу повторить anotherFlow используя значение из someFlow (Значение возвращается, когда это удалось).

Как лучше всего это сделать?

1 ответ

Вы можете использовать retryWhen оператор на anotherFlow как это:

val someFlow = flow { 
    //Some logic that my succeed or throw error 
}

val anotherFlow = flow { 
    // Another logic that my succeed or throe error 
}
.retryWhen { cause, attempt ->
    if (cause is IOException) {    // retry on IOException
        emit(“Some value”)         // emit anything you want before retry
        delay(1000)                // delay for one second before retry
        true
    } else {                       // do not retry otherwise
        false
    }
}

val resultingFlow = someFlow.flatmapLatest(anotherFlow)

Просто будьте осторожны, потому что вы можете повторять попытку бесконечно. Использоватьattempt аргумент, чтобы проверить количество повторных попыток.

Здесь retryWhenофициальная документация оператора: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/retry-when.html

Вы рассматривали возможность использования zip?
Я не тестировал или что-то в этом роде, но, возможно, стоит попробовать.

val someFlow = flow {}
val anotherFlow = flow {}
someFlow.zip(anotherFlow) { some, another ->
    if(another is Resource.Error)
        repository.fetchAnother(some)
    else
        some
}.collect {
    Log.d(TAG, it)
}
Другие вопросы по тегам