RXKotlin Lambda Понимание

Это никогда не завершается:

Completable.complete()
        .andThen{ Completable.complete() }
        .test()
        .assertComplete()

Это завершает:

Completable.complete()
        .andThen(Completable.complete())
        .test()
        .assertComplete()

По словам Джейка Уортона:

«Вы хотите andThen(Completable.complete()). Обратите внимание на использование круглых скобок, а не фигурных скобок. Последние создают лямбду, которая не вызывает свой эмиттер».

Ссылка: https://github.com/ReactiveX/RxJava/issues/5551

Кто-нибудь может объяснить это более подробно? Я думал, что понял лямбду, но это действительно бросило меня.


person Thomas Cook    schedule 30.01.2018    source источник


Ответы (2)


С помощью фигурных скобок вы используете преобразование SAM и определение анонимного экземпляра CompletableSource путем описания его единственного метода внутри лямбды.

Это то же самое, что сделать следующее:

Completable.complete()
        .andThen(object: CompletableSource {
            override fun subscribe(cs: CompletableObserver) {
                Completable.complete()
            }
        })
        .test()
        .assertComplete()

Как видите, внутри этого CompletableSource вы ничего не делаете, кроме как создаете экземпляр Completable и отбрасываете его результат. Чтобы цепочка продолжалась, вам нужно будет вызвать методы для CompleteableObserver, которые вы получили в качестве параметра (например, вы можете вызвать для него onNext() и onComplete()).


Хотя это почти тот же синтаксис, вот версия для Java, если она поможет вам понять вещи:

Completable.complete()
        .andThen(new CompletableSource() {
            @Override
            public void subscribe(CompletableObserver cs) {
                Completable.complete();
            }
        })
        .test()
        .assertComplete();
person zsmb13    schedule 30.01.2018
comment
Отличное объяснение, я, должно быть, очень устал, это имеет смысл. - person Thomas Cook; 30.01.2018
comment
Это одна из тех ошибок, которые, к сожалению, каждый, кто использует Kotlin и Rx, вынужден потратить пару часов на отладку. Это происходит и с другими классами Rx и операторами. - person zsmb13; 30.01.2018
comment
Мозг плавится :D это то же самое, что причиняет боль моему мозгу, когда я пытаюсь выучить Haskell. - person Thomas Cook; 30.01.2018

  1. Допустимый пример в скобках работает следующим образом:

    Completable.complete() выполняется и затем передается в качестве аргумента andThen.

  2. Недопустимый вариант просто передает лямбду в фигурных скобках в качестве аргумента функции andThen, которая становится реализацией (благодаря преобразование SAM) из CompletableSource< /а>. Он никогда не выполняется. Ниже показано, что вы делаете:

    val compl = CompletableSource { Completable.complete() }
    Completable.complete()
        .andThen (compl)
        .test()
        .assertComplete()
        .assertComplete()
    
person s1m0nw1    schedule 30.01.2018