组合 flatMap 不返回预期的上下文结果类型

Combine flatMap returning no expected contextual result type

HomeRepositoryImpl 中是 getWorldWideData 函数,其中 returns AnyPublisher

func getWorldwideData() -> AnyPublisher<WorldwideResponseItem, ErrorType> {
    let url = RestEndpoints.worldwideStats.endpoint()
    let publisher: AnyPublisher<WorldwideResponseItem, ErrorType> = RestManager().fetchData(url: url)
    
    return publisher
        .flatMap {
            let filteredCountries = Array([=10=].countries.sorted(by: {[=10=].totalConfirmed > .totalConfirmed}).prefix(3))
            [=10=].countries = filteredCountries
            return Just([=10=])
        }
}

FlatMap 从发布者那里获取 WorldResponseItemWorldResponseItemcountries 数组 属性我想对其进行排序,因此我创建了名为 filteredCountries 的新变量,并将其值更改为包含 3 个排序国家/地区的数组,然后我更改了 WorldResponseItem 国家 属性 到 filteredCountries 并且 flatMap 返回只是来自发布者的 WorldResponseItem

但是我得到 没有 'flatMap' 候选人产生预期的上下文结果类型 'AnyPublisher<WorldwideResponseItem, ErrorType>' 错误,当我添加 .eraseToAnyPublisher () 到管道,我得到 表达式类型不明确,没有更多上下文

您的 flatMap 中存在多个问题。您需要在 flatMap 内的 Just 上调用 setFailureTypeeraseToAnyPublisher,然后在 flatMap 本身上调用 eraseToAnyPublisher

在使用嵌套闭包时,您还应该使用命名闭包参数 - 您在 flatMap.

中嵌套了一个 sorted(by:)
func getWorldwideData() -> AnyPublisher<WorldwideResponseItem, ErrorType> {
    let url = RestEndpoints.worldwideStats.endpoint()
    let publisher: AnyPublisher<WorldwideResponseItem, ErrorType> = RestManager().fetchData(url: url)

    return publisher
        .flatMap { response -> AnyPublisher<WorldwideResponseItem, ErrorType> in
            let filteredCountries = Array(response.countries.sorted(by: { [=10=].totalConfirmed > .totalConfirmed }).prefix(3))
            response.countries = filteredCountries
            return Just(response).setFailureType(to: ErrorType.self).eraseToAnyPublisher()
        }
        .eraseToAnyPublisher()
}

但是,您一开始就不应该使用 flatMap。您只是将输出映射到不同的值,因此您可以简单地使用 map,这大大简化了闭包。

func getWorldwideData() -> AnyPublisher<WorldwideResponseItem, ErrorType> {
    let url = RestEndpoints.worldwideStats.endpoint()
    let publisher: AnyPublisher<WorldwideResponseItem, ErrorType> = RestManager().fetchData(url: url)

    return publisher
        .map { response -> WorldwideResponseItem in
            let filteredCountries = Array(response.countries.sorted(by: { [=11=].totalConfirmed > .totalConfirmed }).prefix(3))
            response.countries = filteredCountries
            return response
        }
        .eraseToAnyPublisher()
}