如何让两个Combine Publisher依次执行?Zip操作符无法实现需求
解决Combine中串行执行两个Publisher的问题
你用zip操作符的问题在于,它是并行订阅两个Publisher,只会在两个Publisher都各自发出至少一个值时,才会把这两个值配对返回。如果你的第一个Publisher(resetPasscodeConfirmationPublisher)执行完成但没有发出值,或者第二个Publisher先完成并发出值,就会出现只收到第二个响应的情况。
要实现「第一个执行完成后再触发第二个」的串行逻辑,应该用flatMap操作符:
基础版(仅需要第二个Publisher的结果)
let resetPasscodeConfirmationPublisher = authUseCase.resetPasscodeConfirmation(phoneNumber: phoneNumber, code: pincode, passcode: passcode) resetPasscodeConfirmationPublisher .flatMap { _ in // 等待第一个Publisher完成后,再启动第二个 authUseCase.getAccessToken(passcode: passcode) } .sink { completion in print(completion) } receiveValue: { token in print("获取到的Token:\(token)") } .store(in: &cancellables)
进阶版(需要同时获取两个Publisher的结果)
如果需要保留第一个Publisher的返回值,在flatMap里把两个结果组合起来即可:
// 假设第一个Publisher的返回类型是ResetConfirmationResult,第二个是AuthToken resetPasscodeConfirmationPublisher .flatMap { resetResult -> AnyPublisher<(ResetConfirmationResult, AuthToken), Error> in authUseCase.getAccessToken(passcode: passcode) .map { token in (resetResult, token) } .eraseToAnyPublisher() } .sink { completion in print(completion) } receiveValue: { resetResult, token in print("重置密码确认结果:\(resetResult)") print("获取到的Token:\(token)") } .store(in: &cancellables)
关键说明
flatMap会等待第一个Publisher发出值并完成后,才会创建并订阅第二个Publisher,完全符合你的串行执行需求。- 如果第一个Publisher执行失败(进入
.failure状态),flatMap会直接触发sink的completion,不会执行第二个Publisher,这也符合业务逻辑——第一个操作失败的话,第二个操作没必要继续。
内容的提问来源于stack exchange,提问作者mars_dev
相关产品推荐
相关产品推荐

