简体   繁体   中英

RxSwift With UiTextField

Im new to RxSwift and what Im trying is perform the following,

  • User type is search UiTextField
  • App must wait 1 sec after user finish typing to make sure not to hit the Api with each letter write or delete button pressed.
  • App hit my Api for search

I tried the below code as example

class DestinationSearch: UIViewController {
    

    let searchTF = UITextField()    
    var disposeBag = DisposeBag()


    override func viewDidLoad() {
        super.viewDidLoad()

        setUpUI()
        
        
        searchTF.rx.controlEvent(.editingChanged)
            .throttle(.milliseconds(1000), scheduler: MainScheduler.instance)
            .withLatestFrom(searchTF.rx.text)
        .subscribe(onNext:{ query in
            print(self.hitSomeApi(query: query ?? "--"))
        }).disposed(by: disposeBag)

    }

func hitSomeApi(query: String) -> String {
        return query + " Response from API"
    }

When I run the app and start typing I get the the Response from API message with each letter or backspace button pressed! why the throttle delay is not working? Im I doing something wrong here?

Any help will be much appreciated

Based on your description of the problem, it seems like the debounce operator is more suitable than throttle . debounce only emits an element if a certain time, in which nothing has been emitted, has passed, whereas throttle ensures that elements are emitted at least a certain time interval apart.

I can confirm that your code using throttle is working as I'd expect - if I type very quickly, the "Response from API" messages appear roughly every 1 second. If I type very slowly, slower than 1 keystroke per second, then the messages come whenever I press a key. In other words, whenever there is an editing changed event, throttle checks to see if there was a previous one less than 1 second ago. If there is, ignore this new one.

If you use debounce however (the same code, just replace throttle with debounce ), then after each keystroke, it would wait for 1 second to see if the text field is going to change again. It would only emit the editing changed event if it has waited and there is no more editing changed events. So if you keep typing at a pace higher than 1 keystroke per second, no elements will ever be emitted by the observable. This seems to be what you want.

You can compare these two operators on RxMarbles (they are called slightly different names there):

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM