Confusion about flatMapLatest in RxSwift

leizh00701 picture leizh00701 · May 26, 2016 · Viewed 13k times · Source

I learn the sample code in RxSwift. In the file GithubSignupViewModel1.swift, the definition of validatedUsername is:

validatedUsername = input.username //the username is a textfiled.rx_text
    .flatMapLatest { username -> Observable<ValidationResult> in
        print("-------->1:")
        return validationService.validateUsername(username)
            .observeOn(MainScheduler.instance)
            .catchErrorJustReturn(.Failed(message: "Error contacting server"))
    }
    .shareReplay(1)

the validateUsername method is finally called the following method:

func usernameAvailable(username: String) -> Observable<Bool> {
    // this is ofc just mock, but good enough
    print("-------->2:")
    let URL = NSURL(string: "https://github.com/\(username.URLEscaped)")!
    let request = NSURLRequest(URL: URL)
    return self.URLSession.rx_response(request)
        .map { (maybeData, response) in
            print("-------->3:")
            return response.statusCode == 404
        }
        .catchErrorJustReturn(false)
}

Here is my confusion:

whenever I input a character quickly in the username textfield, message -------->1:, -------->2: showed, and a little later message -------->3: showed, but only showed one -------->3: message.

When I input characters slower, message -------->1:, -------->2:, -------->3: showed successively.

But when I change the flatMapLatest to flatMap, how many characters I input, I will get the same number of -------->3: message.

So how did the flatMapLatest work here?

How the flatMapLatest filter the early response from NSURLResponse ?


I read some about the flatMapLatest, but none of them will explain my confusion.

What I saw is something like:

let a = Variable(XX)
a.asObservable().flatMapLatest(...)

When changed a.value to another Variable, the Variable(XX) will not influence the subscriber of a.

But the input.username isn't changed, it is always a testfield.rx_text! So how the flatMapLatest work?

Answer

dangthaison.91 picture dangthaison.91 · May 27, 2016

TheDroidsOnDroid's answer is clear for me:

FlatMapLatest diagram

Well, flatMap() gets one value, then performs long task, and when it gets the next value, previous task will still finish even when the new value arrives in the middle of the current task. It isn’t really what we need because when we get a new text in the search bar, we want to cancel the previous request and start another. That’s what flatMapLatest() does.

http://www.thedroidsonroids.com/blog/ios/rxswift-examples-3-networking/

You can use RxMarbles app on Appstore to play around with operators.