.sink 没有从 Future Publisher 返回承诺值
Posted
技术标签:
【中文标题】.sink 没有从 Future Publisher 返回承诺值【英文标题】:.sink is not returning the promise values from a Future Publisher 【发布时间】:2020-06-03 17:49:01 【问题描述】:我在 lrvViewModel.swift 中有这段代码
func getVerificationID (phoneNumber: String) -> Future<String?, Error>
return Future<String?, Error> promise in
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) (verificationID, error) in
if let e = error
promise(.failure(e))
return
print("verification worked")
self.defaults.set(verificationID, forKey: "authVerificationID")
return promise(.success(verificationID))
然后我在像这样的另一个文件中调用并订阅发布者
let _ = lrvViewModel.getVerificationID(phoneNumber: (lrvViewController?.textField.text)!)
.sink(receiveCompletion:
print("Error worked")
// does a bunch of stuff
, receiveValue:
print("completion worked")
// does a bunch of stuff
)
我没有收到任何构建时错误,但每当我运行应用程序时,GetVerificationID 函数运行良好(打印“验证有效”),但 .sink 中的代码没有运行(我没有收到任何打印语句)。怎么回事?
编辑:
我的解决方案是放弃 combine 并返回到 RXSwift,代码很简单:
var validateObs = PublishSubject<Any>()
func getVerificationID (phoneNumber: String)
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) (verificationID, error) in
if let e = error
print("v error")
self.validateObs.onError(e)
return
self.defaults.set(verificationID, forKey: "authVerificationID")
self.validateObs.onCompleted()
和
lrvViewModel.getVerificationID(phoneNumber: (lrvViewController?.textField.text)!)
let _ = lrvViewModel.validateObs.subscribe(onError:
let e = $0
print(e.localizedDescription)
// do stuff
, onCompleted:
// do stuff
)
希望不依赖依赖,但 RxSwift 实现要容易得多。
如果有人知道合并未来问题的解决方案,请发布!我仍然想知道 wtf 正在发生。很有可能(并且很可能)我只是使用错误的组合。
编辑 2:
使用组合错误。我可以像这样复制我使用 RXSwift 的代码:
let verifyPub = PassthroughSubject<Any, Error>()
func getVerificationID (phoneNumber: String)
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) (verificationID, error) in
if let e = error
self.verifyPub.send(completion: .failure(e))
return
print("verification worked")
self.defaults.set(verificationID, forKey: "authVerificationID")
self.verifyPub.send(completion: .finished)
和
let subs = Set<AnyCancellable>()
let pub = lrvViewModel.verifyPub
.sink(receiveCompletion: completion in
if case let .failure(error) = completion
print("Error worked")
// do stuff
else
print("completion worked")
// do stuff
, receiveValue: _ in
print("this will never happen")
).store(in: &subs)
我不明白,在 combine 中,接收器只有两个结果,一个完成或一个值,并且完成被分成多个案例。而在 RxSwift 中,您有 OnNext、OnComplete 和 OnError。
向来自 raywanderlich.com 的有关组合的书大喊。好东西。
【问题讨论】:
打印“验证有效”吗? 是的! auth 函数工作正常,只是没有从 promise(.success()) 调用返回值。 你实际上不需要return
promise
。您只需执行它,就像您对 .failure
: promise(.success(verificationID))
所做的那样,但我认为这不是问题所在。其他一切对我来说都是正确的。
【参考方案1】:
发生的情况是您的.sink
后面没有.store
命令,因此管道在任何值有机会下降之前就已经不存在了。
您将管道分配给空的_
有效地掩盖了问题。编译器试图警告您,然后您将其关闭。
【讨论】:
真的,我不应该回答,而是将其作为***.com/a/60241460/341994 的副本关闭。这已经在这里处理了无数次了。以上是关于.sink 没有从 Future Publisher 返回承诺值的主要内容,如果未能解决你的问题,请参考以下文章
Kafka Connect JDBC Sink 连接器:如何删除没有 NULL 值的记录?