如何使用Swift Combine实现多网络请求并行+链式调用需求
问题原因
- 报错本质是类型不匹配:Combine要求链式调用中所有Publisher的
Failure类型完全对齐,且函数最终返回需要手动调用eraseToAnyPublisher()执行类型擦除,才能得到要求的AnyPublisher类型 - 多层依赖的链式调用只需要按顺序追加
flatMap即可,不需要嵌套回调
正确实现代码
// 首先修正函数参数定义,原始代码的参数默认值写法不符合Swift语法规范 func overallFunc(arg1: String, arg2: String, arg3: String, arg4: String ) -> AnyPublisher<String?, Error> { let pub1 = func1(arg1: arg1, arg2: arg2) let pub2 = func2(arg1: arg3, arg2: arg4) return Publishers.Zip(pub1, pub2) // 第一个flatMap:请求1、2全部完成后发起请求3,显式声明返回值类型解决编译器歧义 .flatMap { response1, response2 -> AnyPublisher<String?, Error> in return func3(arg1: response1.attribute1, arg2: response2.attribute2) } // 第二个flatMap:请求3完成后发起请求4 .flatMap { response3 -> AnyPublisher<String?, Error> in // 此处根据func4的实际入参要求传值即可,示例直接用请求3的返回结果作为入参 return func4(arg1: response3) } // 执行类型擦除,匹配函数返回值要求 .eraseToAnyPublisher() } // 以下为配套的请求方法类型参考,确保返回值和上述调用的类型对齐即可 func func1(arg1: String, arg2: String) -> AnyPublisher<String?, Error> { // 你的URLSession封装实现示例 return URLSession.shared.dataTaskPublisher(for: URL(string: "请求1地址")!) .map { _ in "请求1返回结果" } .mapError { $0 as Error } .eraseToAnyPublisher() } // func2、func3、func4的实现逻辑和返回值类型与func1保持一致即可
补充说明
如果需要增加失败重试、返回结果校验的逻辑,可以在对应flatMap之前插入tryMap、retry等操作符,整个链式结构完全符合Combine声明式写法的要求。
内容的提问来源于stack exchange,提问作者avocado
相关产品推荐
相关产品推荐

