如何使用Publishers.CombineLatest来获得1个发布者 [英] how to use Publishers.CombineLatest to get 1 publisher

查看:51
本文介绍了如何使用Publishers.CombineLatest来获得1个发布者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用2个发布者,并将它们流式传输到从这两个值映射的1个发布者.

I am trying to use 2 publishers and have them stream to 1 publisher that is mapped from both values.

我的代码是:

class ViewModel {

    let email = CurrentValueSubject<String, Never>("")

    lazy var isEmailValid = email.map { self.validateEmail(email: $0) }

    let password = CurrentValueSubject<String, Never>("")

    lazy var isPasswordCorrect = password.map {
        self.validatePassword(password: $0)
    }

    let canLogin: CurrentValueSubject<Bool, Never>

    private func validateEmail(email: String) -> Bool {
        return email == "1234@gmail.com"
    }

    private func validatePassword(password: String) -> Bool {
        return password == "1234"
    }


    init() {
    
        canLogin = Publishers
            .CombineLatest(isEmailValid, isPasswordCorrect)
            .map { $0 && $1 } 

    }
}

然后在初始化中出现此错误:

Then in the init I get this error:

    //error: Cannot assign value of type 
'Publishers.Map<Publishers.CombineLatest<Publishers.Map<CurrentValueSubject<String, Never>, 
Bool>, Publishers.Map<CurrentValueSubject<String, Never>, Bool>>, Bool>' to type 'CurrentValueSubject<Bool, Never>'

我是新手,所以我感到有些困惑.从上面的代码中,我应该如何实现2个发布者isEmailValid和isPasswordCorrect的组合,成为1个发布者,该发布者是CurrentValueSubject< Bool,Never> ;?

I am new to combine so I find it a little confusing. How should I achieve, from the code above, the combination of 2 publishers isEmailValid and isPasswordCorrect, into 1 publisher that is a CurrentValueSubject<Bool, Never>?

推荐答案

A CurrentValueSubject 是:

一个主题,它包装一个值并在值更改时发布一个新元素.

A subject that wraps a single value and publishes a new element whenever the value changes.

您的 canLogin 当然不是 CurrentValueSubject .这是使用 CombineLatest 运算符将其他两个发布者合并,然后将合并的发布者映射到另一个发布者的结果.

Your canLogin is certainly not a CurrentValueSubject. It is the result of combining two other publishers with the CombineLatest operator, and then mapping the combined publisher to yet another publisher.

在Swift类型系统的语言中,这种发布者称为:

In the language of the Swift type system, this kind of publisher is called:

Publishers.Map<Publishers.CombineLatest<Publishers.Map<CurrentValueSubject<String, Never>, Bool>, Publishers.Map<CurrentValueSubject<String, Never>, Bool>>, Bool>

很显然,没有人会声明具有这种类型的属性,因此我们使用 eraseToAnyPublisher 来获得一个 AnyPublisher ,表示我们实际上并不在乎它是什么类型的发布商.

Obviously, no one would declare a property with a type like that, so we use eraseToAnyPublisher to get ourselves an AnyPublisher, to say that we don't actually care what type of publisher it is.

let canLogin: AnyPublisher<Bool, Never>

...

canLogin = Publishers
        .CombineLatest(isEmailValid, isPasswordCorrect)
        .map { $0 && $1 } 
        .eraseToAnyPublisher()

这篇关于如何使用Publishers.CombineLatest来获得1个发布者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆