ReactiveX / RxSwift

Reactive Programming in Swift
MIT License
24.35k stars 4.16k forks source link

Confusing about the usage of flatMapLatest in the example code of GithubSignupViewModel1.swift #712

Closed leizh007 closed 8 years ago

leizh007 commented 8 years ago

In the file GithubSignupViewModel1.swift, the definition of validatedUsername is:

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

The validateUsername will finally called the following method:

 func usernameAvailable(username: String) -> Observable<Bool> {
     // this is ofc just mock, but good enough
     print("message2")
     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("message3")
             return response.statusCode == 404
        }
         .catchErrorJustReturn(false)
 }

The input.username is a textfield.rx_text, when I input the character in the textfield quickly before the network request returned: message1 and message2 showed as many times as the characters I input, but message3 only showed once. If I changed the flatMapLatest to flatMap, the number of times that message3 showed is equal to the characters' count. How did the flatMapLatest work?


I searched the document and read some articles online, all of those explanation of flatMapLatest is like following:

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

When changed a.value to another value, the Variable(XXX) will not influence the subscriber of a. But the question above is input.name isn't changed! It is always the textfield.rx_text.

leizh007 commented 8 years ago

I get another flatMapLatest explanation in https://github.com/baconjs/bacon.js/wiki/Diagrams, and this solved my confusion. I think it should give more explanation in document.