.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()) 调用返回值。 你实际上不需要returnpromise。您只需执行它,就像您对 .failure: promise(.success(verificationID)) 所做的那样,但我认为这不是问题所在。其他一切对我来说都是正确的。 【参考方案1】:

发生的情况是您的.sink 后面没有.store 命令,因此管道在任何值有机会下降之前就已经不存在了。

您将管道分配给空的_ 有效地掩盖了问题。编译器试图警告您,然后您将其关闭。

【讨论】:

真的,我不应该回答,而是将其作为***.com/a/60241460/341994 的副本关闭。这已经在这里处理了无数次了。

以上是关于.sink 没有从 Future Publisher 返回承诺值的主要内容,如果未能解决你的问题,请参考以下文章

akka 流 toMat

如何从cassandra事件流中获取最后一个事件

Kafka Connect JDBC Sink 连接器:如何删除没有 NULL 值的记录?

从`async fn`返回的future的具体类型是啥?

调用 StreamController.sink.add 时 StreamBuilder 没有反应

如何从 boost log sink 组织线程安全读取?