Первый трюк, который приходит на ум, - это materialize
.Это будет конвертировать каждый Observable<T>
в Observable<Event<T>>
, поэтому ошибка будет просто .next(.error(Error))
и не приведет к завершению последовательности.
в данном конкретном случае, хотя другой трюк будетнеобходимо.Помещение всей цепочки "триггеров" в плоскую карту, а также materialize
в этот конкретный фрагмент.Это необходимо, потому что материализованная последовательность все еще может завершиться, что приведет к завершению в случае обычной цепочки, но не завершит цепочку flatMapped (как выполнено == успешно выполнено внутри flatMap).
inputRelay
.flatMapLatest { val in
return Observable.just(val)
.map { value -> Int in
if value == 1 { throw SomeError.randomError }
return value + value
}
.flatMap { value in
return Observable<String>.just("hey\(value)")
}
.materialize()
}
.debug("k")
.subscribe()
inputRelay.accept(1)
inputRelay.accept(2)
inputRelay.accept(3)
inputRelay.accept(4)
Это выведет следующее для k
:
k -> subscribed
k -> Event next(error(randomError))
k -> Event next(next(hey4))
k -> Event next(completed)
k -> Event next(next(hey6))
k -> Event next(completed)
k -> Event next(next(hey8))
k -> Event next(completed)
Теперь все, что вам нужно сделать, это отфильтровать только «следующие» события из материализованной последовательности.
Если у вас есть RxSwiftExt , вы можете просто использовать операторы errors()
и elements()
:
stream.elements()
.debug("elements")
.subscribe()
stream.errors()
.debug("errors")
.subscribe()
Это обеспечит следующий вывод:
errors -> Event next(randomError)
elements -> Event next(hey4)
elements -> Event next(hey6)
elements -> Event next(hey8)
При использовании этой стратегии не забывайте добавлять share()
после вашей flatMap
, поэтому многие подписки не вызывают многократной обработки.
Вы можете узнать больше о том, почему вы должны использовать share в этой ситуации здесь: http://adamborek.com/how-to-handle-errors-in-rxswift/
Надеюсь, это поможет!