почему concat never() в rxswift

func signup(_ username: String, password: String) -> Observable<Bool> {
    // this is also just a mock
    let signupResult = arc4random() % 5 == 0 ? false : true
    return Observable.just(signupResult)
        .concat(Observable.never())
        .throttle(0.4, scheduler: MainScheduler.instance)
        .take(1)
 }

Я вижу код в RxSwift , Но я не мог понять, зачем нужно concat(Observable.never())


person 常小波    schedule 27.11.2016    source источник


Ответы (3)


Я сам в этом разбираюсь, так что прими это с недоверием :)

  • Observable.just выдает значение один раз и сразу завершается; практически не занимает времени;
  • .throttle(0.4, scheduler: MainScheduler.instance) вводит время в последовательность, занимая 0,4 с+, чтобы определить возвращаемое значение, и
  • concat(Observable.never()) делает входную последовательность продолжительной, поэтому throttle нужно что-то делать в первую очередь.

Теперь return Observable.just(signupResult) будет достаточно для реализации этой функции. Чем хороши остальные?

Остальные три оператора приводят к задержке. Поскольку конкатенированный Observable не имеет конца, throttle будет ждать не менее 0,4 секунды один раз, чтобы определить, какое значение выдать для первого дросселированного «чанка». take(1) затем завершает последовательность, когда первое значение выдается через 0,4 с.

Мне кажется, это очень трудоемкий способ реализации отложенного ответа :)

person ctietze    schedule 28.11.2016

Это просто пример. FUI, never создайте Observable, который не создает никаких элементов и не прерывается (описание из официального документация)

person Artem Novichkov    schedule 27.11.2016
comment
Спасибо, я знаю использование never, поэтому я не понимаю, зачем использовать never(), так что это просто пример~ - person 常小波; 28.11.2016

Ответ от @ctietze кажется правильным. Но после теста я понимаю, что throttle убивает всю концепцию. В основном throttle вернет значение сразу после наблюдаемого начала. Это означает, что он не будет ждать, пока 0.4s выдаст первое значение.

func testWithThrottle() -> Observable<Int> {
        return
            Observable.just(7) // 1
                .concat(Observable.never()) // 2
                .throttle(3.0, scheduler: Schedulers.background) // 3
                .take(1) // 4

        // 1. -7--|->
        // 2. -7------------------------------->
        // 3. -7------------------------------->
        // 4. -7--|->
}

...

print("[\(Date())] Start!")
testWithThrottle().subscribe({ (event) in
    print("[\(Date())] event: \(event)")
}).addDisposableTo(disposeBag)
print("[\(Date())] End!")

...

[2017-06-03 03:14:00 +0000] Start!
[2017-06-03 03:14:00 +0000] event: next(7)
[2017-06-03 03:14:00 +0000] event: completed
[2017-06-03 03:14:00 +0000] End!

Итак, какое решение? Легко, вместо этого вам нужно использовать debounce.

func testWithDebounce() -> Observable<String> {
        return
            Observable.of("A") // 1
                .concat(Observable.never()) // 2
                .debounce(3.0, scheduler: Schedulers.background) // 3
                .take(1) // 4

        // 1. -A-|->
        // 2. -A------------------------------>
        // 3. ---------------A---------------->
        // 4. ---------------A-|->
}

...

[2017-06-03 03:24:21 +0000] Start Thrrotle!
[2017-06-03 03:24:21 +0000] Finish Thrrotle!
[2017-06-03 03:24:24 +0000] event: next(A)
[2017-06-03 03:24:24 +0000] event: completed
person nahung89    schedule 03.06.2017