switchToLatest в Combine не работает должным образом - PullRequest
0 голосов
/ 17 октября 2019

Я пытался реплицировать flatMapLatest из RxSwift в Combine, я читал в нескольких местах, что решение заключается в использовании .map(...).switchToLatest

Я нахожу некоторые различия между этими двумя, и я не уверен, что проблема заключается в моей реализации / понимании.

В RxSwift, если наблюдаемая восходящая ветвь генерирует событие остановки (завершено или ошибка), тогда наблюдаемые нижестоящие потоки создаются в закрытии flatMapLatestбудет продолжать излучать события до тех пор, пока они сами не отправят событие остановки:

let disposeBag = DisposeBag()

func flatMapLatestDemo() {
    let mockTrigger = PublishSubject<Void>()
    let mockDataTask = PublishSubject<Void>()

    mockTrigger
        .flatMapLatest { mockDataTask }
        .subscribe(onNext: { print("RECEIVED VALUE") })
        .disposed(by: disposeBag)

    mockTrigger.onNext(())
    mockTrigger.onCompleted()

    mockDataTask.onNext(()) // -> "RECEIVED VALUE" is printed
}

Эта же настройка в Combine ведет себя не так:

var cancellables = Set<AnyCancellable>()

func switchToLatestDemo() {
    let mockTrigger = PassthroughSubject<Void, Never>()
    let mockDataTask = PassthroughSubject<Void, Never>()

    mockTrigger
        .map { mockDataTask }
        .switchToLatest()
        .sink { print("RECEIVED VALUE") }
        .store(in: &cancellables)

    mockTrigger.send(())
    mockTrigger.send(completion: .finished)

    mockDataTask.send(()) // -> Nothing is printed, if I uncomment the finished event above then "RECEIVED VALUE" is printed
}

Является ли это преднамеренным? Если да, то как нам повторить поведение flatMapLatest в Комбинате?

Если это не преднамеренно, подать, я полагаю, радар?

1 Ответ

0 голосов
/ 19 октября 2019

Я использовал эту реализацию Swift от sergdort :

func flatMapLatest<T: Publisher>(_ transform: @escaping (Self.Output) -> T) -> Publishers.SwitchToLatest<T, Publishers.Map<Self, T>> where T.Failure == Self.Failure {
    map(transform).switchToLatest()
}
...