FlatMap未向下游发送完成事件问题咨询
问题分析与解决方案
你遇到的核心问题是:当在uploadFS中使用sink订阅上游Publisher时,事件会被sink完全消耗,无法传递给下游的flatMap。
原因解释
sink是终端订阅者,调用它会立即触发对上游Publisher的订阅,所有输出值和完成事件都会被这个sink处理。而普通Publisher(比如combineLatest返回的类型)是单播的,事件只能被一个订阅者接收。你在uploadFS里用sink+store,相当于把上游事件截留在方法内部,下游的flatMap根本拿不到这个Publisher的任何事件,自然收不到完成信号。
正确的做法
如果你既想处理事件(比如打印日志),又要把事件传递给下游,应该用handleEvents操作符——它不会消耗事件,只是在事件流的各个阶段插入自定义逻辑,之后事件会继续向下游传递。
修改后的uploadFS代码示例:
func uploadFS() -> AnyPublisher<[Common_Empty], Never> { let requests = makeRequests() return requests .combineLatest() .handleEvents( receiveCompletion: { completion in Log.info("\(completion)") }, receiveOutput: { value in Log.info("Recieved value: \(value)") } ) .eraseToAnyPublisher() }
如果确实需要将返回类型改为Void,可以通过map将输出转换为Void,同时保留事件流:
func uploadFS() -> AnyPublisher<Void, Never> { let requests = makeRequests() return requests .combineLatest() .handleEvents( receiveCompletion: { completion in Log.info("\(completion)") }, receiveOutput: { value in Log.info("Recieved value: \(value)") } ) .map { _ in () } // 将输出转为Void .eraseToAnyPublisher() }
这样修改后,上游的完成事件就能正常传递到下游的flatMap中了。
内容的提问来源于stack exchange,提问作者Iskander Nizamov
相关产品推荐
相关产品推荐

