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

Combine框架多异步请求错误处理:适配差异化故障响应需求

解决Combine中Zip操作符的差异化错误处理需求

你的核心需求是让两个请求的错误处理逻辑分离:学生API失败必须终止流程并提示错误,地址API失败则用默认值继续执行。可以通过为地址请求添加错误兜底逻辑,再结合Zip操作符来实现,具体方案如下:

修改思路

  • 学生API请求:保留原有错误抛出逻辑,一旦失败,整个流会进入错误状态,在sink的receiveCompletion中处理并显示错误。
  • 地址API请求:使用catch操作符捕获错误,返回一个包含空地址数组的默认发布者,确保该请求永远不会抛出错误,让Zip能正常接收它的输出(即使是默认值)。

修改后的完整代码

import Foundation
import Combine

enum NetworkError: Error {
    case decodingError
    case requestFailed
}

struct StudentDTO: Codable {
    let name: String
    let age: Int
    let addressId: Int
}

struct AddressDTO: Codable {
    let id: Int
    let town: String
}

struct Student {
    let name: String
    let age: Int
    let town: String
}

func m1<T: Codable>(url: String, type: T.Type) -> Future<T, NetworkError> {
    return Future { promise in
        // 这里替换为实际的URLSessionDataTask请求逻辑
    }
}

// 声明一个用于存储订阅的变量,避免订阅被提前释放
var cancellables = Set<AnyCancellable>()

// 处理地址API的错误:失败时返回空数组
let addressRequest = m1(url: "", type: [AddressDTO].self)
    .catch { _ in
        Just([AddressDTO]()) // 错误时返回空的地址数组
    }

Publishers.Zip(
    m1(url: "", type: [StudentDTO].self),
    addressRequest
)
.sink(receiveCompletion: { completion in
    if case .failure(let error) = completion {
        // 仅当学生API失败时会进入这里,显示错误信息
        print("学生API请求失败:\(error)")
    }
}, receiveValue: { studentList, addresses in
    // 正常处理逻辑,地址API失败时addresses是空数组
    let addressDict = addresses.reduce(into: [Int: String]()) { dict, address in
        dict[address.id] = address.town
    }
    let students = studentList.map { student in
        Student(
            name: student.name,
            age: student.age,
            town: addressDict[student.addressId] ?? ""
        )
    }
    // self?.processStudents(students: students)
})
.store(in: &cancellables)

关键细节说明

  1. 地址请求的错误兜底:catch操作符会捕获地址请求的所有错误,返回Just([AddressDTO]())——这是一个立即发射空数组的发布者,确保地址请求的流永远不会进入失败状态,Zip操作符就能正常等待两个请求完成。
  2. 学生请求的错误传递:学生请求没有添加错误处理,所以一旦它失败,整个Zip流会触发receiveCompletion的.failure分支,在这里可以处理错误提示逻辑。
  3. 数据处理兼容:当地址API失败时,addresses是空数组,转换后的addressDict也是空字典,学生的town会使用默认值"",符合业务中"继续运行"的需求。

内容的提问来源于stack exchange,提问作者nath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:01:19