2015-12-30 1 views
1

Это короткая версия моего кода, который будет воспроизводить эту проблему:delaySubscription не работает с rx_tap

import UIKit 
import RxSwift 
import RxCocoa 

class ViewController: UIViewController { 
    @IBOutlet weak var button: UIButton! 

    let disposeBag = DisposeBag() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let source = button.rx_tap.map { _ in "source" } 

     let delay = source.map { _ in "delayed" } 
      .delaySubscription(2.0, MainScheduler.sharedInstance) 

     [source, delay].toObservable().merge() 
      .subscribeNext { print($0) } 
      .addDisposableTo(disposeBag) 
    } 
} 

Я хочу «замедленное» сигнал к огню через 2 секунды после того, как я нажимаю кнопку, но не такая удача. Что на самом деле происходит: в первый раз, когда я нажимаю кнопку, «источник» срабатывает, но больше ничего не происходит. Затем, когда я снова нажимаю «источник» и «задерживает» огонь в одно и то же время. Я понял, что это проблема с потоком, поэтому я попробовал добавить observeOn(MainScheduler.sharedInstance) всюду, но это не помогло. Есть идеи?

Обновление: добавив .debug() к потокам, я узнал, что отложенный поток фактически подписывается на источник через 2 секунды. Но это все еще не объясняет, почему он не запускает свои уведомления через 2 секунды.

ответ

2

Чтобы ответить на мой вопрос, кажется, что delaySubscription работает только на холодных наблюдаемых.

Простуда, наблюдаемая, например, timer, только начинает загораться уведомления, когда она была подписана, и все, кто подписывается на нее, получают новую последовательность. Вот почему просто задержка подписки на холодный наблюдаемый также задерживает все уведомления.

Горячий наблюдаемый, например, как пользовательский интерфейс, разделяет одну и ту же последовательность со всеми его абонентами, поэтому отсрочка подписки абсолютно не влияет на его уведомления.

Вместо этого я могу использовать оператор flatMap преобразовать каждое уведомление источника в другой наблюдаемую, стреляющие свое единственное уведомление после некоторой задержки, и объединяют результаты этих наблюдаемые:

class ViewController: UIViewController { 
@IBOutlet weak var button: UIButton! 

let disposeBag = DisposeBag() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let source = button.rx_tap.map { _ in "source" } 

    let delayed = source.flatMap { _ in 
     timer(1.0, MainScheduler.sharedInstance) 
      .map { _ in "delayed" } 
    } 

    [source, delayed] 
     .toObservable().merge() 
     .subscribeNext { print($0) } 
     .addDisposableTo(disposeBag) 
    } 
} 
Смежные вопросы