Будущее комбината никогда не завершается, когда flatMapped - PullRequest
2 голосов
/ 22 января 2020

У меня есть следующее простое Future:

class ViewModel {
    var cancellables = Set<AnyCancellable>()
    func test() {
        let trigger = PassthroughSubject<Void, Error>()

       let future =  Future<String, Error> { promise in
                       promise(.success("Future Succeded"))
                   }

        trigger
        .flatMap { future }
        .sink(receiveCompletion: { completion in
            print("completion received \(completion)")
        }, receiveValue: { val in
            print("value received \(val)")
        })
        .store(in: &cancellables)

        trigger.send(())
    }
}

Я не знаю, почему оно никогда не завершается при плоском сопоставлении с другим издателем (в данном случае PassthroughSubject), оно производит только значение.

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

1 Ответ

4 голосов
/ 22 января 2020

Это поведение может выглядеть странно, но оно имеет большой смысл. Завершение Future не завершает PassthroughSubject. Таким образом, вы можете продолжить отправку значений через PassthroughSubject, что приведет к созданию и запуску новых экземпляров Future. Как правило, Publisher может завершиться только или ошибка один раз. Таким образом, если завершение Future вызовет закрытие завершения sink, это означает, что PassthroughSubject больше не может выдавать новых значений, что нежелательно, поскольку PassthroughSubject обычно никогда не завершается (если вы не скажете это напрямую).

Как и в вашем примере, этот код также запускает завершение только один раз:

var cancellables = Set<AnyCancellable>()

(0..<2).publisher
  .flatMap { _ in return (0..<5).publisher }
  .sink(receiveCompletion: { completion in
    print("completion received \(completion)")
  }, receiveValue: { val in
    print("value received \(val)")
  })
  .store(in: &cancellables)

Причина в том, что созданный издатель публикует sh два значения, а затем завершает , Если издатель flatMap вызовет завершение sink, это будет означать, что издатель (0..<2) завершает работу, за исключением того, что у него все еще есть значения для отправки, поэтому он не завершен.

Короче говоря начинающий издатель решает, когда поток завершится; не раскрученный издатель.

...