微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

结合:Just 和 first() 之间的区别来完成一个流

如何解决结合:Just 和 first() 之间的区别来完成一个流

我是 Combine 的新手,我不了解这些情况下的行为:

func getPublisherWithFirst() -> AnyPublisher<Value,Error> {
    // somePublisher: PassthroughSubject<Bool,Never>
    return somePublisher
        .compactMap { (someBool) -> Value? in
            if someBool {
                return Value()
            }
            return nil
        }
        .setFailureType(to: Error.self)
        .first()
        .timeout(.seconds(5),scheduler: dispatchQueue.main)
        .erasetoAnyPublisher()
}
func getPublisherWithFlatMap() -> AnyPublisher<Value,Never>
    return somePublisher
        .flatMap { (someBool) -> AnyPublisher<Value,Never> in
            if someBool {
                return Just(Value()).erasetoAnyPublisher()
            }
            return Empty(completeImmediately: false,outputType: Value.self,failureType: Never.self).erasetoAnyPublisher()
        }
        .setFailureType(to: Error.self)
        .timeout(.seconds(5),scheduler: dispatchQueue.main)
        .erasetoAnyPublisher()
}

使用 getPublisherWithFlatMap 时,我的流不会结束(触发超时),即使返回了 Just 发布者并且它应该结束。为什么?

解决方法

“问题”是由您使用 PassthroughSubject 作为上游引起的。 PassthroughSubject 永远不会完成,除非您明确发送完成。

使用 first 时,上游是否完成并不重要,因为只要 first 的上游发出单个值,它就会完成。但是,在 flatMap 的情况下,flatMap 对其上游发出的每个值执行其闭包,因此它仅在其上游完成时完成。您在 Just 中返回 flatMap 无关紧要,Just 只会返回单个值,而不是整个上游。

如果您想确保 getPublisherWithFlatMap 在发出单个值后也完成,您也应该对其调用 first,类似于 getPublisherWithFirst

func getPublisherWithFlatMap() -> AnyPublisher<Value,Error> {
    // somePublisher: PassthroughSubject<Bool,Never>
    return somePublisher
        .flatMap { (someBool) -> AnyPublisher<Value,Never> in
            if someBool {
                return Just(Value()).eraseToAnyPublisher()
            }
            return Empty(completeImmediately: false,outputType: Value.self,failureType: Never.self).eraseToAnyPublisher()
        }
        .setFailureType(to: Error.self)
        .first()
        .timeout(.seconds(5),scheduler: DispatchQueue.main)
        .eraseToAnyPublisher()
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。