RxSwift запускает наблюдаемое выполнение - PullRequest
0 голосов
/ 26 апреля 2018

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

Я могу использовать ReplaySubject буфера 1 и publish() метод. Однако сетевой запрос выполняется только один раз.

Я хотел бы вызвать событие извлечения в любой заданной точке в будущем. Как я могу вызвать новый запрос?

В настоящее время у меня есть Service объект, который содержит ReplaySubject и имеет метод reload(), который запускает сетевой запрос и публикует результат в ReplaySubject.

Есть ли на Observable какой-либо метод, который может "обновить" его и доставить новое значение всем текущим подписчикам?

1 Ответ

0 голосов
/ 01 мая 2018

Если я правильно интерпретирую этот вопрос, это довольно распространенная проблема в RxSwift. Вы должны иметь возможность пересоздавать ваш сетевой запрос Observable каждый раз, когда ваша выборка «инициируется», но вам нужны эти результаты, доставленные на одном Observable, который создается только один раз и имеет несколько подписчиков. Это делается с помощью flatMap:

struct Service {
    var resultsObservable: Observable<Results> {
        return resultsSubject.asObservable()
    }

    private let resultsSubject: ReplaySubject<Results> = .create(bufferSize: 1)
    private let reloadSubject = PublishSubject<Void>()
    private let disposeBag = DisposeBag()

    init() {
        bindFetch()
    }

    func reload() {
        reloadSubject.onNext(())
    }

    private func bindFetch() {
        reloadSubject
            .asObservable()
            .flatMap(fetch)
            .bind(to: resultsSubject)
            .disposed(by: disposeBag)
    }

    private func fetch() -> Observable<Results> {
        // URLSession just one example
        let urlRequest = URLRequest(url: URL(string: "https://apple.com")!)
        return URLSession
            .shared
            .rx
            .data(request: urlRequest)
            .map(Results.init)
            .catchErrorJustReturn(Results.empty())
    }
}

В этом примере вы можете подписаться на resultsObservable несколько раз, и каждый из них должен обновляться после появления нового reload().

...