使用Swift中的Combine进行2个请求的序列。

huangapple go评论66阅读模式
英文:

Make a sequence of 2 requests with Combine in Swift?

问题

我有以下的代码:

import Combine

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

login()
    .flatMap { response -> Future<Status, Error> in
        // 处理响应并在本地保存令牌
        return updateImage()
    }
    .sink(receiveCompletion: { error in
        ... // 处理错误
    }, receiveValue: { response in
        ... // 处理响应和不同的错误
    })
    .store(in: ...)

我想要将 login()updateImage() 连接成一个序列。但是,我发现 zip 只适用于并行请求。我需要一种方法来按顺序链接它们,我不确定 maptryMapmapError 方法是否能帮助我实现这一点。我不仅需要转换,还需要处理每个函数的响应数据和错误。

如何解决这个问题?

英文:

I have the following code:

import Combine

func login() -&gt; Future&lt;Token, Error&gt; { ... }
func updateImage() -&gt; Future&lt;Status, Never&gt; { ... }

login()
    .flatMap { response -&gt; Future&lt;Status, Error&gt; 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: ...)

I want to join login() and updateImage() into a sequence. However, I found that zip is only for parallel requests. I need a way to chain them sequentially, and I am not sure if map, tryMap, or mapError methods can help me achieve that. I need to not only transform but also handle the response data and errors from each function.

How to solve this issue?

答案1

得分: 1

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

.flatMap { response -> Future<Status, Never> in // 将 "Error" 更改为 "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()
}
英文:

In iOS 14+, there is a new overload of flatMap that allows you flat map to a publisher that Never fails, so you just need to change the explicit return type of your closure to match the type that updateImage returns:

.flatMap { response -&gt; Future&lt;Status, Never&gt; in // change &quot;Error&quot; to &quot;Never&quot;

Prior to iOS 14, you would need to use setFailureType(to:):

.flatMap { response -&gt; Publishers.SetFailureType&lt;Future&lt;Status, Never&gt;, Error&gt; in
    // ...
    return updateImage().setFailureType(to: Error.self)
}

If you don't like such a long type name, use AnyPublisher:

.flatMap { response -&gt; AnyPublisher&lt;Status, Error&gt; in
    // ...
    return updateImage().setFailureType(to: Error.self).eraseToAnyPublisher()
}

huangapple
  • 本文由 发表于 2023年6月16日 13:29:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76487188.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定