Изучение программирования на Kotlin

Kotlin Flow Buffer похож на модное воплощение

Визуализируйте буфер Kotlin Flow, легко объединяйте и собирайте последнее

В документации Kotlin Flow он разделяет 3 типа буферов, то есть Buffer, Conflate и CollectLatest. Они позволяют Kotlin Flow испускать элементы до того, как предыдущий будет полностью обработан, что обеспечивает параллелизм.

Работа с тремя буферами немного отличается. Мне потребовалось время, чтобы понять их различия. Тогда я понимаю, что если я сравниваю их с одним принятием моды, то это тоже легко и легко запомнить.

Буфер… покупатель, получающий все

Покупатель, который берет все, захочет обработать все доступные платья. Если покупатель не может использовать платье вовремя, портнихе разрешается изготовить только максимальное количество платьев, которое может хранить буфер, а затем подождать, пока покупатель сможет взять буферное платье (2), прежде чем производить следующее платье ( 3).

В конце Заказчик потребляет все сгенерированные платья.

fun dressMaker(): Flow<Int> = flow {
    for (i in 1..3) {
        println("Dress $i in the making")
        delay(100)
        println("Dress $i ready for sale")
        emit(i)
    }
}

fun main() = runBlocking<Unit> {
    dressMaker()
        .buffer()
        .collect { value ->
            println("Dress $value bought for use")
            delay(300)
            println("Dress $value completely used")
        }
}

Результат, как показано ниже (все одеты израсходованы)

Dress 1 in the making
Dress 1 ready for sale
Dress 2 in the making
Dress 1 bought for use
Dress 2 ready for sale
Dress 3 in the making
Dress 3 ready for sale
Dress 1 completely used
Dress 2 bought for use
Dress 2 completely used
Dress 3 bought for use
Dress 3 completely used

Вы заметите, что все платья (1, 2 и 3) куплены для использования и полностью использовались.

Используя Buffer, сторона Терминала захочет иметь все сгенерированные элементы. Если Терминал работает медленно, то передатчик ожидает, пока Терминал завершит обработку своего элемента, прежде чем выдать следующий элемент.

Объедините ... бережливого покупателя

Точно так же, как покупатель, получающий все, экономный покупатель будет использовать купленное платье (1) до тех пор, пока оно не закончится. Если новое платье (2) готово в буфере, бережливый покупатель не купит его, пока он не закончит носить текущее платье.

Однако портниха продолжит выпускать платья. Если будет произведено новое платье (3), то платье из буфера будет удалено. Следовательно, бережливый покупатель упустит снятое платье (2).

fun dressMaker(): Flow<Int> = flow {
    for (i in 1..3) {
        println("Dress $i in the making")
        delay(100)
        println("Dress $i ready for sale")
        emit(i)
    }
}

fun main() = runBlocking<Unit> {
    dressMaker()
        .conflate()
        .collect { value ->
            println("Dress $value bought for use")
            delay(300)
            println("Dress $value completely used")
        }
}

Результат

Dress 1 in the making
Dress 1 ready for sale
Dress 2 in the making
Dress 1 bought for use
Dress 2 ready for sale
Dress 3 in the making
Dress 3 ready for sale
Dress 1 completely used
Dress 3 bought for use
Dress 3 completely used

Вы заметите платья, которые куплены для использования, а также сшитые. Но не все платья покупаются для подержанного, т.е. платье 2 выпадает, потому что оно было доступно до того, как платье 1 было полностью использовано.

Платье 3, наконец, покупается, так как оно было в буфере, и после платья 3 новое платье не производится.

Используя conflate, он удаляет любой новый элемент, который он получил, всякий раз, когда новый элемент доступен. Если Терминал работает медленно, он не сможет потреблять все произведенные элементы, поскольку некоторые из них были удалены (например, элемент 2 выше).

CollectLatest… модный покупатель

В отличие от бережливого покупателя, модный покупатель всегда следит за тем, чтобы у него было самое последнее платье. Когда новое платье будет готово (2), оно удалит свое текущее платье (1), даже если оно еще не закончено.

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

fun dressMaker(): Flow<Int> = flow {
    for (i in 1..3) {
        println("Dress $i in the making")
        delay(100)
        println("Dress $i ready for sale")
        emit(i)
    }
}

fun main() = runBlocking<Unit> {
    dressMaker()
        .collectLatest { value ->
            println("Dress $value bought for use")
            delay(300)
            println("Dress $value completely used")
        }
}

Тогда результат

Dress 1 in the making
Dress 1 ready for sale
Dress 1 bought for use
Dress 2 in the making
Dress 2 ready for sale
Dress 2 bought for use
Dress 3 in the making
Dress 3 ready for sale
Dress 3 bought for use
Dress 3 completely used

Вы заметите, что все платья куплены для использования, но только платье 3 готово.

Используя collectLatest, он удаляет обрабатываемый в данный момент элемент всякий раз, когда доступен новый элемент. На приведенной выше диаграмме, когда элемент 2 готов, элемент 1 отбрасывается. Когда элемент 3 готов, элемент 2 отбрасывается. Только элемент 3 завершил процесс, так как после него не появилось никаких новых элементов.

Надеюсь, эта простая аналогия значительно упростит изучение типа буферов 3 Kotlin.