FlatMapПоследний триггер пропускается до тех пор, пока не будет завершено последнее наблюдаемое - PullRequest
0 голосов
/ 01 апреля 2019

Я пытаюсь создать код, который будет выполнять какой-то неудавшийся длительный запрос на конкретное действие пользователя, но игнорировать печальное действие, пока запрос активен.Цель состоит в том, чтобы позволить нажать на кнопку, пока не будет успешной передачи по запросу.Все ошибки пропущены.До сих пор я пришел к такому коду, но не могу понять, что делать дальше:

struct ErrorError: Error {}
var emitSuccess: Bool = false

// should be something like button.rx.tap
let buttonTap = PublishSubject<Void>()

let requestDuration: RxTimeInterval = 5
let tapInterval: RxTimeInterval = 3


let requestTrigger = buttonTap
    // ???
    .flatMapLatest { (_) -> Observable<Bool> in
        // imitation of http request/parsing etc.
        if emitSuccess {
            return Observable.just(true)
                .delay(requestDuration, scheduler: MainScheduler.instance)
                .debug("response success", trimOutput: false)
        } else {
            emitSuccess = true
            return Observable.error(ErrorError())
                .materialize()
                .delay(requestDuration, scheduler: MainScheduler.instance)
                .dematerialize()
                .debug("response failure", trimOutput: false)
                .catchErrorJustComplete()
        }
    }
    .take(1) //supposed to dispose observation of taps
    .share(replay: 1, scope: .forever)

let requestResponse = requestTrigger
    .debug("response", trimOutput: false)
    .subscribe()

// imitate button tap
Observable<Int>.interval(tapInterval, scheduler: MainScheduler.instance)
    .takeUntil(Observable.just(true).delay(20, scheduler: MainScheduler.instance))
    .debug("button tap imitation", trimOutput: false)
    .subscribe(onNext: { (value) in
        buttonTap.onNext(())
        return
    })

В своей текущей форме каждое нажатие обнаруживает незавершенное наблюдаемое и запускает новое, что нежелательно."???"это место, где, как я полагаю, должен быть какой-то умный оператор регулирования / пропускания.

Вещи, которые приходят на ум:

  • заменить "???"с takeUntil(requestResponse), что приведет к какой-то странной рекурсивной подписке (это даже разрешено / хорошо / плохо?)
  • использовать concatMap вместо flatMapLatest, но это своего рода очереди и в этом случаеесли возникает какая-либо ошибка (например, без подключения к Интернету), она, вероятно, будет возникать для всех нажатий в очереди> запросов, что означает, что мне нужно пропустить нажатий
  • создать свою собственную Наблюдаемую (используя createdeferred и т. Д.)

1 Ответ

0 голосов
/ 01 апреля 2019

К стыду, как оказалось, ответ на этот вопрос был на поверхности - я должен был просто использовать flatMapFirst. Как я вижу, многие rx-операторы имеют неочевидные значения и варианты использования, и лучший способ привыкнуть к ним - это практика и чтение.

BTW этот хороший пост , хотя вид повторяющейся документации все же немного лучше перефразирует ее и был именно тем, что я прочитал через 10 минут после того, как написал этот вопрос (facepalm) (хотя я мог только что прочитать документация всех операторов и в конце концов найду тот, который мне нужен).

...