Javascript RxJS-reduce不';我不能继续

Javascript RxJS-reduce不';我不能继续,javascript,reactive-programming,rxjs,reactive-extensions-js,Javascript,Reactive Programming,Rxjs,Reactive Extensions Js,为什么flatMap不会导致下游减少着火 我得到的代码如下: 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', fi

为什么flatMap不会导致下游减少着火

我得到的代码如下:

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'));
问题是“减少后”轻敲从未被击中。为什么?

日志如下所示:

reduce step [data]
reduce step [data]
截图:


问题不在
flatMap
;它妨碍了
reduce
的工作

读取整个流并将其减少为单个值,仅在源流关闭时发出。如果来自(文件)的
流没有结束,则
reduce
将永远不会输出其值


试着用它来代替;它发出每个中间步骤,似乎就是您要查找的内容。

如果文件是一个数组,那么如果fileReader返回的可观察内容是数组,则reduce应该终止。因此,对于这段代码,问题在于fileReader返回了一个未完成的observable

使用windowTime:

import { fromEvent, interval, timer } from 'rxjs';
import { reduce, filter, windowTime, map, mergeMap } from 'rxjs/operators';

const interval$ = interval(1000);
const observable = interval$.pipe(
  windowTime(2000), // each window is 2s
  mergeMap(window$ => window$.pipe(
    reduce((a,x) => { // reduce to array
      return [...a,x];
    }, []),
    filter(x => !!x.length) // in the background timer is still running so suppress empty events
  )), // flatten the Observable-of-Observables
);
const subscription = observable.subscribe(x => console.log(x));
setTimeout(() => subscription.unsubscribe(), 10000);
使用缓冲时间:

import { fromEvent } from 'rxjs';
import { bufferTime, filter, map } from 'rxjs/operators';

let count = 1;
const clicks = fromEvent(document, 'click');
const observable = clicks.pipe(
  bufferTime(1000), // batch into array every 1s
  filter(x => !!x.length), // ignore events without clicks
  map(x => x.reduce((a,y) => ({...a, [count++]: y}), {})),
);
observable.subscribe(x => console.log(x));
使用审核时间:

import { fromEvent } from 'rxjs';
import { tap, auditTime, map } from 'rxjs/operators';

let buffer = [];
const clicks = fromEvent(document, 'click');
const observable = clicks.pipe(
  tap((event) => buffer.push(event)),
  auditTime(1000), // buffer every 1s after 1st click is detected
  map((_lastEvent) => { // ignore last event
    const events = buffer; // save off buffer
    buffer = []; // clear buffer
    return events.reduce((a,e,i) => ({...a, [i]: e}),{});
  }),
);
observable.subscribe((events) => console.log(events));
使用takeUntil并重复:

注意:take/repeat将重置可观测值(即间隔计数器保持为0,事件可能丢失)


文件是一个JS数组,简单明了。我添加了一个截图。我以前做过扫描,确实有效。。。但由于它是一个JS数组聚合,所以应该完成,对吗?不过,这是一个很好的捕获。我发现了我的错误;未在fileReader中完成主题。哼!
import { fromEvent, timer, interval } from 'rxjs';
import { takeUntil, reduce, repeat, filter } from 'rxjs/operators';

const interval$ = interval(1000);
const timer$ = timer(2000);

const observable = interval$.pipe(
  takeUntil(timer$), // unsubscribe from stream every 2s so reduce terminates
  reduce((acc, event) => [...acc, event], []), // reduce to array of events
  filter(x => !!x.length), // suppress emission of empty stream
  repeat(), // resubscribe to stream
);
// console will only show array of [0] since takeUntil stops right when interval emits
const subscription = observable.subscribe(x => console.log(x));
setTimeout(() => subscription.unsubscribe(), 10000);