快速合并替代Rx Observable.create [英] Swift Combine alternative to Rx Observable.create
问题描述
我有一些使用RxSwift构建的代码,并且正在尝试将其转换为使用Apple的Combine框架.
I have some code that is built using RxSwift, and I'm playing around with converting it to use Apple's Combine framework.
一种非常常见的模式是对单次可观察的对象(通常是网络请求)使用 Observable.create
.像这样:
One pattern which is very common is the use of Observable.create
for one-shot observables (usually network requests). Something like this:
func loadWidgets() -> Observable<[Widget]> {
return Observable.create { observer in
// start the request when someone subscribes
let loadTask = WidgetLoader.request("allWidgets", completion: { widgets in
// publish result on success
observer.onNext(widgets)
observer.onComplete()
}, error: { error in
// publish error on failure
observer.onError()
})
// allow cancellation
return Disposable {
loadTask.cancel()
}
}
}
我正在尝试将其映射到Combine,但我还无法弄清楚.我所能获得的最接近的结果是将Future用于类似这样的事情:
I'm trying to map that across to Combine and I haven't been able to quite figure it out. The closest I've been able to get is using Future for something like this:
func loadWidgets() -> AnyPublisher<[Widget], Error> {
return Future<[Widget], Error> { resolve in
// start the request when someone subscribes
let loadTask = WidgetLoader.request("allWidgets", completion: { widgets in
// publish result on success
resolve(.success(widgets))
}, error: { error in
// publish error on failure
resolve(.failure(error))
})
// allow cancellation ???
}
}
如您所见,它完成了大部分操作,但是无法取消.其次,未来不允许多重结果.
As you can see, it does most of it, but there's no ability to cancel. Secondarily, future doesn't allow multiple results.
有什么方法可以执行类似Rx Observable.create
模式的操作,该模式允许取消操作并有可能产生多个结果?
Is there any way to do something like the Rx Observable.create
pattern which allows cancellation and optionally multiple results?
推荐答案
我想我找到了一种在 Combine中使用
.这是我做的帮手: PassthroughSubject
模仿 Observable.create
的方法
I think I found a way to mimic Observable.create
using a PassthroughSubject
in Combine
. Here is the helper I made:
struct AnyObserver<Output, Failure: Error> {
let onNext: ((Output) -> Void)
let onError: ((Failure) -> Void)
let onComplete: (() -> Void)
}
struct Disposable {
let dispose: () -> Void
}
extension AnyPublisher {
static func create(subscribe: @escaping (AnyObserver<Output, Failure>) -> Disposable) -> Self {
let subject = PassthroughSubject<Output, Failure>()
var disposable: Disposable?
return subject
.handleEvents(receiveSubscription: { subscription in
disposable = subscribe(AnyObserver(
onNext: { output in subject.send(output) },
onError: { failure in subject.send(completion: .failure(failure)) },
onComplete: { subject.send(completion: .finished) }
))
}, receiveCancel: { disposable?.dispose() })
.eraseToAnyPublisher()
}
}
使用情况如下:
func loadWidgets() -> AnyPublisher<[Widget], Error> {
AnyPublisher.create { observer in
let loadTask = WidgetLoader.request("allWidgets", completion: { widgets in
observer.onNext(widgets)
observer.onComplete()
}, error: { error in
observer.onError(error)
})
return Disposable {
loadTask.cancel()
}
}
}
这篇关于快速合并替代Rx Observable.create的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!