在 Swift 中使用 Combine 发出 2 个请求的序列?

Make a sequence of 2 requests with Combine in Swift?

提问人:Gargo 提问时间:6/16/2023 最后编辑:Gargo 更新时间:6/16/2023 访问量:50

问:

我有以下代码:

import Combine

func login() -> Future<Token, Error> { ... }
func updateImage() -> Future<Status, Never> { ... }

login()
    .flatMap { response -> Future<Status, Error> in
        // handle response and save token locally
        return updateImage()
    }
    .sink(receiveCompletion: { error in
        ... //handleError
    }, receiveValue: { response in
        ... // handle response and a different error
    })
    .store(in: ...)

我想加入并进入一个序列。但是,我发现这仅适用于并行请求。我需要一种方法来按顺序链接它们,我不确定 、 或 方法是否可以帮助我实现这一目标。我不仅需要转换,还需要处理每个函数的响应数据和错误。login()updateImage()zipmaptryMapmapError

如何解决这个问题?

Swift Sequence Future 联合 发行商

评论

0赞 Gargo 6/16/2023
我创建了“嵌套”请求,但 Combin(和其他库)通常也会在您调用时提供语法 - 无需嵌套。或者,如果 Combine 不允许这样做?Futuresfuture.someHandler(...).someHandler2(...).someHandler3(...)...
0赞 Gargo 6/16/2023
尝试了 flatMap - 现在我收到错误在 iOS 13 中不可用flatMap
0赞 Sweeper 6/16/2023
对于您发布的代码,情况并非如此。你把它平面映射到什么?您是否正在尝试平铺映射到失败的发布者?这确实会调用 iOS 13 中不可用的 flatMap 过载Never
0赞 Sweeper 6/16/2023
是的,仅适用于 iOS 14 之前的相同错误类型。您是否有不同的错误类型?如果是这样,请编辑问题以反映这一点。flatMap
0赞 Gargo 6/16/2023
@Sweeper 很抱歉,我真的在第二次通话中使用了。但是如何在iOS 13中处理它呢?Never

答:

1赞 Sweeper 6/16/2023 #1

在 iOS 14+ 中,有一个新的 flatMap 重载,允许您将平面映射到失败的发布者,因此您只需要更改闭包的显式返回类型以匹配返回的类型:NeverupdateImage

.flatMap { response -> Future<Status, Never> in // change "Error" to "Never"

在 iOS 14 之前,您需要使用:setFailureType(to:)

.flatMap { response -> Publishers.SetFailureType<Future<Status, Never>, Error> in
    // ...
    return updateImage().setFailureType(to: Error.self)
}

如果您不喜欢这么长的类型名称,请使用:AnyPublisher

.flatMap { response -> AnyPublisher<Status, Error> in
    // ...
    return updateImage().setFailureType(to: Error.self).eraseToAnyPublisher()
}