问题
I am trying to simulate merging 2 different Observable streams, which are emitting some object every second. This object has the same Parent in those 2 streams.
I thought, that in the console will appear new object with value after 1 second. However, when i print those objects, i get objects that skipped the previous emission. So like object with value 1, 3, 5, 7 etc.
However, in the buffer, which merges those two it seems that it only buffer the 2, 4, 6, 8 etc. emissions.
Here is my code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var counter = 0
var counter2 = 0
val periodicSomeClass1 = Observable.interval(1, TimeUnit.SECONDS)
.flatMap(
{
counter++
Observable.just(SomeClass1("$counter", counter))
}
)
val periodicSomeClass2 = Observable.interval(1, TimeUnit.SECONDS)
.flatMap(
{
counter2++
Observable.just(SomeClass2(counter2.toDouble()))
}
)
periodicSomeClass1.subscribe { t: SomeClass1 -> Log.v("periodicSomeClass1", t.toString()) }
periodicSomeClass2.subscribe { t: SomeClass2 -> Log.v("periodicSomeClass2", t.toString()) }
Observable.merge(periodicSomeClass1, periodicSomeClass2)
.buffer(10, TimeUnit.SECONDS)
.doOnSubscribe { Log.v("bufferObservable", "STARTED") }
.subscribe { t: MutableList<Parent> ->
Log.v("bufferObservable", "onNext")
t.forEach { Log.v("onNext", it.toString()) }
}
}
And here is what i have in the Log output with first buffer/merge emsission:
V/periodicSomeClass1: SomeClass1(a=1, b=1)
V/periodicSomeClass2: SomeClass2(a=1.0)
V/periodicSomeClass1: SomeClass1(a=3, b=3)
V/periodicSomeClass2: SomeClass2(a=3.0)
V/periodicSomeClass1: SomeClass1(a=5, b=5)
V/periodicSomeClass2: SomeClass2(a=5.0)
V/periodicSomeClass1: SomeClass1(a=7, b=7)
V/periodicSomeClass2: SomeClass2(a=7.0)
V/periodicSomeClass1: SomeClass1(a=9, b=9)
V/periodicSomeClass2: SomeClass2(a=9.0)
V/periodicSomeClass1: SomeClass1(a=11, b=11)
V/periodicSomeClass2: SomeClass2(a=11.0)
V/periodicSomeClass1: SomeClass1(a=13, b=13)
V/periodicSomeClass2: SomeClass2(a=13.0)
V/periodicSomeClass1: SomeClass1(a=15, b=15)
V/periodicSomeClass2: SomeClass2(a=15.0)
V/periodicSomeClass1: SomeClass1(a=17, b=17)
V/periodicSomeClass2: SomeClass2(a=17.0)
V/periodicSomeClass1: SomeClass1(a=19, b=19)
V/periodicSomeClass2: SomeClass2(a=19.0)
V/bufferObservable: onNext
V/onNext: SomeClass1(a=2, b=2)
V/onNext: SomeClass2(a=2.0)
V/onNext: SomeClass1(a=4, b=4)
V/onNext: SomeClass2(a=4.0)
V/onNext: SomeClass1(a=6, b=6)
V/onNext: SomeClass2(a=6.0)
V/onNext: SomeClass1(a=8, b=8)
V/onNext: SomeClass2(a=8.0)
V/onNext: SomeClass1(a=10, b=10)
V/onNext: SomeClass2(a=10.0)
V/onNext: SomeClass1(a=12, b=12)
V/onNext: SomeClass2(a=12.0)
V/onNext: SomeClass1(a=14, b=14)
V/onNext: SomeClass2(a=14.0)
V/onNext: SomeClass1(a=16, b=16)
V/onNext: SomeClass2(a=16.0)
V/onNext: SomeClass1(a=18, b=18)
回答1:
Like you correctly suspected in the comment on your other question, this problem is indeed related.
1.) You are subscribing twice to both of your source observables, once directly for each of them and once through the subscription to the merge
d Observable.
2.) So you then have four Observables running in total, where two of them are incrementing (and reading from) counter
and the other two are incrementing (and reading from) counter2
.
3.) For each of these pairs the two intervals are ever so slightly offset and each flatMap
from the first of each pair sees the value n
, increments it to n+1
and prints it. Then shortly afterwards, the other instance comes along and sees n+1
, increments to n+2
, prints that, etc.
Finally, the buffer
hides that all of this happens interleaved because it prints all the even values after all the odd ones.
Any solution really depends on what you want to achieve - is this just a playground example, or does it model some real problem?
来源:https://stackoverflow.com/questions/47368711/why-i-have-undesired-log-output-when-merging-2-observables-into-other-observable