Below is a simplified version of my code. The problem is that the finally block is executed early than I would like. I would like it to execute only when all the other Observables are done.
let data1 = 'test1'
let data2 = 'test2'
const input = Rx.Observable.from([data1, data2])
.finally(() => {
console.log('end')
})
let output = input.concatMap((text) => {
let promise = Promise.resolve(text)
return Rx.Observable.fromPromise(promise)
})
output.subscribe((x) => {console.log(x)})
Output:
end
test1
test2
Expected output:
test1
test2
end
The problem you have is that Observable.from
emits everything immediately and completes. Then both emissions are buffered inside concatMap
but the source has already completed so the finally
block is called.
The easiest thing you can do is just put the finally
block after concatMap
because that's when it's really done:
const data1 = 'test1';
const data2 = 'test2';
const input = Observable.from([data1, data2]);
const output = input
.concatMap(text => Promise.resolve(text))
.finally(() => console.log('end'));
output.subscribe(console.log);
See live demo (open console): https://stackblitz.com/edit/rxjs5-hnesmn?file=index.ts
Btw, if you really need .finally
right after Observable.from
you can't get the output you want because .finally
is called when Observable.from
is disposed (completed or errored), which is independent of the chain that follows. In other words Observable.from
can't know when the following chain completes. It wouldn't even make sense because the Rx contract dictates that there's always only one complete
or error
notification. But if you used eg. Observable.from().finally().share()
then you could have multiple subscribes and what would decide when the source Observable calls finally()
? It can complete only once.
Try to change the subscription logic and see whether you get what you are looking for
output.subscribe(
(x) => {console.log(x)},
error => console.error(error),
() => console.log('Finally I have really reached the END')
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.