gpt4 book ai didi

ios - 将 URLSession.DataTaskPublisher 转换为 Future 发布者

转载 作者:行者123 更新时间:2023-12-03 23:27:40 24 4
gpt4 key购买 nike

如何转换 URLSession.DataTaskPublisherFuture在组合框架中。
在我看来, Future 发布者在这里更合适,因为调用只能发出一个响应并最终失败。

在 RxSwift 中有像 asSingle 这样的辅助方法.

我使用以下方法实现了这种转换,但不知道这是否是最好的方法。

        return Future<ResponseType, Error>.init { (observer) in
self.urlSession.dataTaskPublisher(for: urlRequest)
.tryMap { (object) -> Data in
//......
}
.receive(on: RunLoop.main)
.sink(receiveCompletion: { (completion) in
if case let .failure(error) = completion {
observer(.failure(error))
}
}) { (response) in
observer(.success(response))
}.store(in: &self.cancellable)
}
}

有什么简单的方法可以做到这一点吗?

最佳答案

据我了解,使用 .asSingle 的原因在 RxSwift 中,当您订阅时,您的订阅者会收到一个 SingleEvent这是一个 .success(value).error(error) .因此,您的订阅者不必担心收到 .completion事件类型,因为没有。

没有与Combine 中的等价物。在Combine 中,从订阅者的角度来看,Future只是另一种 Publisher它可以发出输出值和 .finished.failure(error) .类型系统不强制执行 Future 的事实。从不发出 .finished .

因此,没有程序上的理由返回 Future具体来说。你可以争辩说返回 Future记录您始终只返回一个输出或失败的意图。但这不会改变您编写订阅者的方式。

此外,由于Combine 大量使用泛型,只要您想将任何运算符应用于Future ,你已经没有 future 了。如果您申请 map给一些 Future<V, E> ,你会得到一个 Map<Future<V, E>, V2> , 和其他每个运算符类似。这些类型很快就失控并掩盖了存在 Future 的事实。在底部。

如果你真的想,你可以实现你自己的操作符来转换任何 PublisherFuture .但是你必须决定如果上游发出 .finished 该怎么办, 因为 Future无法发射 .finished .

extension Publisher {
func asFuture() -> Future<Output, Failure> {
return Future { promise in
var ticket: AnyCancellable? = nil
ticket = self.sink(
receiveCompletion: {
ticket?.cancel()
ticket = nil
switch $0 {
case .failure(let error):
promise(.failure(error))
case .finished:
// WHAT DO WE DO HERE???
fatalError()
}
},
receiveValue: {
ticket?.cancel()
ticket = nil
promise(.success($0))
})
}
}
}

关于ios - 将 URLSession.DataTaskPublisher 转换为 Future 发布者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60428303/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com