RxJava combine Observable with another optional Observable with timeout

ⅰ亾dé卋堺 提交于 2021-01-29 04:32:16

问题


Asume we have two observables A and B. A publishes a result certainly, while the result from B might not be published at all (timeout).

The question is how to map the result from A and B if B returns within a timeframe, otherwise just return the result from A.

Observable<DatabaseObject> A = getDatabaseElement();
Observable<NetworkObject> B = restApi.getElement();

Map example:

map((databaseObject, networkObject) => {
  databaseObject.setData(networkObject);
  return databaseObject;
})

回答1:


In order to timeout B observable use take operator with time argument:

B.take(10, TimeUnit.SECONDS)

In order to receive either A or B (if B is ready within timeout) use concatWith:

A.concatWith(B.take(10, TimeUnit.SECONDS))
    .takeLast(1)

In case you wish to combine A and B (optionally enrich A with B):

A.concatWith(B.take(10, TimeUnit.SECONDS))
    .reduce((a, b) -> a.setData(b))

In case A and B are of different types (optionally enrich A with B):

Observable.combineLatest(
    A,
    B.take(10, TimeUnit.SECONDS).defaultIfEmpty(stubB)),
    (a, b) -> { if (b != stubB) a.setData(b); }
)



回答2:


You might want to take a different approach here .. There is an operator designed exactly for the behavior you described. Take a look at .timeout(long time, TimeUnits units, Observable backupObservable) which instructs a stream to switch from the original observable (in your case B, the network request I assume) to the backup A observable when there are no other items in the original stream for the specified amount of time.



来源:https://stackoverflow.com/questions/41762526/rxjava-combine-observable-with-another-optional-observable-with-timeout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!