为什么 Empty Publisher 不会在 Combine 中触发完成事件?

问题描述

我们知道Combine中的Empty Publisher会立即触发一个完成事件:

Empty<Void,Never>()
    .sink {
        print("completion: \($0)")  // will print!
    } receiveValue: {}

但是 flatMap 返回的 Empty Publisher 不会触发完成事件:

var subs = Set<AnyCancellable>()
let p0 = PassthroughSubject<[Int],Error>()
let p1 = p0
    .flatMap {_ in
        Empty<Void,Never>() // same Empty Publisher
    }.erasetoAnyPublisher()

p1
    .sink {
        print("completion: \($0)")  // but NOT print!
    } receiveValue: {}
    .store(in: &subs)

p0.send([1,2,3])

这是为什么???我错过了什么吗???谢谢! ;)

解决方法

FlatMap 的工作方式如下:对于每个上游值,它都会创建一个发布者。下游接收所有这些由 FlatMap 创建的发布者发出的所有值。

它在上游完成时完成,或者如果上游出错或任何创建的发布者出错则出错。

因此,在您的情况下,对于 [1,2,3] 的单个上游值,您发出 Empty 发布者(已完成),但没有整体完成,因为 PassthroughSubject 尚未完成。

p0.send([1,3])
p0.send(completion: .finished)

以上将完成整个管道。