Я пытаюсь выполнить несколько действий последовательно, используя RxSwift, и не уверен, как заставить его работать.

Проблема заключается в возврате наблюдаемой Single, где успех / ошибка зависит от того, успешно или нет вызов Completable.

Моя попытка кода выглядит примерно так:

func doSomething(with value: SomeType) -> Single<SomeType> {
    return repository.replace(with: value) // replace() returns a completable
        .asObservable()
        .flatMap { () -> Single<SomeType> in
            return Single.just(value)
    }
}

Ошибка в строке 4 (flatMap):

Невозможно преобразовать тип результата вызова «Observable <_. E>» в ожидаемый тип «PrimitiveSequence » (он же «PrimitiveSequence »)

Как я могу сопоставить этот выполнимый к одному?

7
Yasir 28 Май 2017 в 21:36

2 ответа

Лучший ответ

Спустя всего несколько месяцев после того, как я ответил на этот вопрос, к типу Completable был добавлен новый оператор. .andThen . Использование делает этот код намного проще:

func doSomething(with value: SomeType) -> Single<SomeType> {
    return repository.replace(with: value)
        .andThen(Single.just(value))
}

Оригинальный ответ следует:

Хм ... Completable никогда не испускает элемент, поэтому нет ничего для flatMap. И.Е. нет смысла даже использовать оператор flatMap в Completable. Единственное, что вы можете с этим сделать, это подписаться на него.

Следовательно, вам нужно реализовать свой метод следующим образом:

func doSomething(with value: SomeType) -> Single<SomeType> {
    return Single<SomeType>.create { observer in
        return repository.replace(with: value)
            .subscribe(onCompleted: {
                observer(.success(value))
            }, onError: {
                observer(.error($0))
            })
    }
}

Я пытался работать с Observables, которые не генерируют значения в прошлом, до этих новомодных типов, и я всегда считал их болью. На вашем месте я бы преобразовал ваш метод replace так, чтобы он возвращал Single<Void> вместо Completable. т.е .:

func replace(with value: SomeType) -> Single<Void> 

Если вы это сделаете, то вы можете просто:

func doSomething(with value: SomeType) -> Single<SomeType> {
    return repository.replace(with: value).map { value }
}

Конечно, если вы можете это сделать, то вы могли бы также replace(with:) возвращать Single<SomeType>.

8
Daniel T. 20 Июл 2019 в 14:04

Я не уверен насчет RxSwift, но в RxJava вы могли бы следующее

repository.replace(with: value).andThen(Single.just(value))
14
Wicket 24 Ноя 2017 в 15:56