Ios 联合收割机';人的未来永远不可能完成,当你失败的时候

Ios 联合收割机';人的未来永远不可能完成,当你失败的时候,ios,combine,Ios,Combine,我有以下简单的未来: class ViewModel { var cancellables = Set<AnyCancellable>() func test() { let trigger = PassthroughSubject<Void, Error>() let future = Future<String, Error> { promise in prom

我有以下简单的
未来

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(())
    }
}
类视图模型{
var cancelables=Set()
func测试(){
let trigger=PassthroughSubject()
让未来=未来{承诺未来
承诺(.success(“未来成功”))
}
触发
.flatMap{future}
.sink(receiveCompletion:{completion in
打印(“完成收到\(完成)”)
},receiveValue:{val in
打印(“收到的值\(val)”)
})
.store(在:&可取消项中)
trigger.send(())
}
}
我不知道为什么当平面映射到另一个发布服务器(在本例中是
PassthroughSubject
)时,它永远不会完成,它只生成值


当它不是平面映射时,它会生成值并正常完成。

这种行为可能看起来很奇怪,但很有意义。完成
未来
不会完成
传递主题
。因此,您可以继续通过
PassthroughSubject
发送值,这将导致创建并触发新的
Future
实例。通常情况下,
发布者只能完成或出错一次。因此,如果完成
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)
var cancelables=Set()

(0..当我将
flatMap
更改为
map
并且不做任何进一步的更改时,也不会收到完成。非常好的解释。请注意,在问题示例中,可以通过添加
触发器。发送(完成:。完成)来完成问题
。是的,我的想象是由
.flatMap
制作的出版商将其
.finished
完成版“吞没”因此它不会向下游传递。这是有意义的,因为正如您所说,制作发行商的工作不是通过完成来终止管道的操作。-另一方面,如果制作发行商抛出错误,管道确实会终止。