RXSwift, обнаружена аномалия повторного входа

Я новичок в RXSwift, и у меня проблема с кодом

У меня есть код:

let dartScore = PublishSubject<Int>()
            dartScore.asObservable()
                .scan(501) { intermediate, newValue in
                    let result = intermediate - newValue
                    return result >= 0 ? result : intermediate
                }
                .do(onNext: {
                    if $0 == 0 {
                        dartScore.onCompleted()
                    }
                })
                .subscribe({
                    print($0.isStopEvent ? $0 : $0.element!)
                })
                .disposed(by: disposeBag)

            dartScore.onNext(13)
            dartScore.onNext(50)
            dartScore.onNext(60)
            dartScore.onNext(378)

И я получаю ошибку:

⚠️ Обнаружена аномалия повторного входа. ⚠️

Отладка: для отладки этой проблемы вы можете установить точку останова в /****RxSwift/RxSwift/Rx.swift:97 и наблюдать за стеком вызовов.

Проблема: такое поведение нарушает грамматику наблюдаемой последовательности. next (error | completed)? Такое поведение нарушает грамматику, потому что события последовательности перекрываются. Наблюдаемая последовательность пытается отправить событие до завершения отправки предыдущего события.

почему я не могу выполнить ".onCompleted ()" внутри .do (onNext) и что мне делать, чтобы избежать предупреждения?

Я использую XCode 9.0, swift 4, RXSwift 4.0.0

Спасибо

С уважением


person Seishin Okigaru    schedule 03.12.2017    source источник
comment
Я парень Rx.NET, но предполагаю, что RxSwift ведет себя точно так же, поэтому не делайте .onCompleted() внутри do. Вероятно, вы захотите использовать takeWhile.   -  person Enigmativity    schedule 03.12.2017
comment
Спасибо за предложение, @Enigmtivity, С уважением   -  person Seishin Okigaru    schedule 04.12.2017
comment
У меня возникла эта проблема из-за совершенно несвязанного кода. Если вы просто следуете инструкциям, устанавливаете точку останова и наблюдаете за стеком, вы можете отследить проблему. Что касается меня, я наблюдал за текстовым полем и вычислял и устанавливал другие значения. Таким образом, код для вычисления других значений вызывал view.endEditing(true) и из-за этого переходил в цикл редактирования и завершения редактирования ..   -  person Skywalker    schedule 05.02.2020


Ответы (1)


Вы не можете сделать .onCompleted() внутри .onNext(), потому что в этом случае наблюдаемое будет поедать свой собственный хвост. Это также вызывает цикл памяти.

Как @Enigmativity предлагает в комментариях, вы должны использовать takeWhile() для обработки этой ситуации:

dartScore.asObservable()
    .scan(501) { intermediate, newValue in
        let result = intermediate - newValue
        return result >= 0 ? result : intermediate
    }
    .takeWhile { $0 != 0 }
    .subscribe({
        print($0.isStopEvent ? $0 : $0.element!)
    })

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

person Daniel T.    schedule 03.12.2017
comment
Ой, хорошо, понял, спасибо за ответ :) С уважением - person Seishin Okigaru; 04.12.2017
comment
У меня есть две следующие подряд строчки: observer.onNext("Hello world") ;observer.onCompleted() Это неправильно? - person Honey; 22.06.2019
comment
@Honey Нет, это нормально (при условии, что вы не поместили эти две строки в закрытие, привязанное к observer. - person Daniel T.; 24.07.2020