RxJS reduce doesn't continue

2019-06-20 07:41发布

问题:

Why doesn't the flatMap cause downstream reductions to fire?

I got code like:

handleFiles.flatMap(files =>
  Rx.Observable.from(files).
  flatMap((file, i) => fileReader(file, i)).
  reduce((form, file, i) => {
    form.append('file[' + i + ']', result);
    console.log('reduce step', file);
    return form;
  }, new FormData()).
  tap(console.log.bind(console, 'after reduce'))
).
subscribe(console.log.bind(console, 'response'));

And the problem is that the 'after reduce' tap is never hit. Why?

The log is like:

reduce step [data]
reduce step [data]

Screenshot:

回答1:

The problem isn't in flatMap; it's in the way reduce works.

reduce reads in a whole stream and reduces it to a single value, emitted only when the source stream is closed. If your from(files) stream doesn't end, then reduce will never output its value.

Try using scan instead; it emits each intermediate step and seems to be what you're looking for.



回答2:

If files is an array, then reduce should terminate if the observable returned from fileReader does. So for this code, the problem was that fileReader returned an observable that didn't complete.