简体   繁体   中英

rxjs finally executed before promise resolves

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM