You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让两个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:58:12