2016-07-19 2 views
1

Я использую RxSwift для кэширования в моем приложении IOS и иметь кусок кода, как это:ReactiveX RxSwift получить первую не ошибку от CONCAT наблюдаемых

let observable = Observable.of(cache.getItem(itemID), network.getItem(itemID)).concat().take(1) 

observable.subscribeNext // and do some stuff 

У меня есть cache.getItem метод делает в onError, если он имеет нет значения, и хотелось бы, чтобы он затем отложил работу в сети, но по какой-то причине сеть никогда не запускается. Я предполагаю, потому что я использую take (1), но я хотел бы, чтобы наблюдаемое прекратило излучать, как только кеш найдет что-то (или продолжит работу в сети, если это не так).

Любые идеи о том, как это сделать?

Я слежу за руководством this, но он не разбирается в поведении своего кэша, когда ему не удается найти что-то.

ответ

2

Вы не должны использовать .Error. На самом деле это не концептуально случай ошибки. В кеше ничего нет. Это обычная ситуация. Ничто не пошло не так, как обычно. Вместо этого просто отправьте событие .Completed.

А почему ваш код не работает, это потому, что ошибка идет от Observable, включенных в concat станет ошибкой на заключительном concatObservable. Вещь, которую следует помнить с Rx, заключается в том, что когда есть событие .Completed или (в вашем случае) событие .Error, вот оно, все кончено, не более .Next событий (или любых событий).

Так вместо этого, если вы используете .Completed, ваш код будет работать так:

class Cache { 
    func getItem(itemID: Int) -> Observable<Item> { 
     return Observable<Item>.create { observer in 
      // if not found... 
      observer.onCompleted() // you would of course really try to get it 
            // from the cache first. 
      return NopDisposable.instance 
     } 
    } 
} 

class Network { 
    func getItemN(itemID: Int) -> Observable<Item> { 
     return Observable<Item>.create { observer in 
      // get some `item` from the network and then.. 
      observer.onNext(item) 
      return NopDisposable.instance 
     } 
    } 
} 

let observable = Observable.of(cache.getItem(itemID), network.getItem(itemID)).concat().take(1) 

observable.subscribeNext { item in 
    print(item) 
} 
+1

Отлично, спасибо чувак! Хорошее объяснение и отлично работает – Josh

+0

Прямо сейчас, продолжайте веселиться с Rx! – solidcell

Смежные вопросы