我有一个名为的类,它可以随着时间的推移QueryObserver
产生多个结果,作为回调(闭包)返回。你像这样使用它:
let observer = QueryObserver<ModelType>(query: query) { result in
switch result {
case .success(let value):
print("result: \(value)")
case .failure(let error):
print("error: \(error)")
}
}
(QueryObserver
实际上是 Firebase Firestore 笨拙query.addSnapshotListener
功能的包装器,以防您想知道。使用现代Result
类型而不是具有多个可选参数的回调。)
在一个较旧的项目中,我正在使用 ReactiveKit 并有一个扩展,可以将所有这些转换为Signal
,如下所示:
extension QueryObserver {
public static func asSignal(query: Query) -> Signal<[T], Error> {
return Signal { observer in
let queryObserver = QueryObserver<T>(query: query) { result in
switch result {
case .success(let value):
observer.receive(value)
case .failure(let error):
if let firestoreError = error as? FirestoreError, case .noSnapshot = firestoreError {
observer.receive([])
} else {
observer.receive(completion: .failure(error))
}
}
}
return BlockDisposable {
queryObserver.stopListening()
}
}
}
}
不过,在一个全新的项目中,我正在使用 Combine 并试图重写它。到目前为止,我已经设法写了这个,但它不起作用。这是有道理的:observer
它不会被任何东西保留,所以它会立即被释放,并且什么也没有发生。
extension QueryObserver {
public static func asSignal(query: Query) -> AnyPublisher<[T], Error> {
let signal = PassthroughSubject<[T], Error>()
let observer = QueryObserver<T>(query: query) { result in
switch result {
case .success(let value):
print("SUCCESS!")
signal.send(value)
case .failure(let error):
if let firestoreError = error as? FirestoreError, case .noSnapshot = firestoreError {
signal.send([])
} else {
signal.send(completion: .failure(error))
}
}
}
return signal.eraseToAnyPublisher()
}
}
如何使组合版本工作?如何包装现有的异步代码?我发现的唯一示例用于Future
一次性回调,但随着时间的推移我正在处理多个值。
基本上我正在寻找这个的 ReactiveKit-to-Combine版本。