【问题标题】:Combining an Observable Array of Observable<boolean> to an Observable<boolean[]> - am I doing this right?将 Observable<boolean> 的 Observable 数组组合到 Observable<boolean[]> - 我这样做对吗?
【发布时间】:2017-10-17 07:48:12
【问题描述】:

假设我有一个 Observable 的 Observable 列表:

const a = [Observable.of(false), Observable.of(false)];
const aSbj: Observable<Array<Observable<boolean>>> = new BehaviorSubject(a);

我想将 a 中的所有 Observable 组合成一个 boolean[] 的 Observable。这是我的想法(使用 TypeScript):

const listObs = aSbj
    .switchMap((observables: Array<Observable<boolean>>) => {
      return Observable.combineLatest(...observables);
    });

这似乎可行,并且能够得到我想要的结果,但我的问题是:

  1. 我对 switchMap 的理解正确吗?
  2. 这是否会在每次 aSbj 触发时创建一个新的 Observable?这会对性能产生重大影响吗?

(上下文:)

我的最终目标是将整个布尔值列表映射为 any() 值:

const anyObs = listObs.map((booleans) => {
  return booleans.some(i => i)
});

...这样当我更改 aSbj 时,anyObs 会发出正确的值:

const any;
anyObs.subscribe((anyVal) => any = anyVal); // any == false
aSbj.next([Observable.of(true), Observable.of(false)]);
// any == true

【问题讨论】:

  • 如果您只想将 boolean[] 映射到 any 值,则 booleans 本身不需要是 Observable。他们有什么理由吗?你可以做bools$ = Observable.of([false,false,false]); any$ = bools$.map(arr =&gt; arr.some(b =&gt; b));
  • 我把问题抽象了一点,但是 Observable 是必要的。想象一下,单个布尔值表示一组切换中的切换状态,并且它们的状态会随着时间而变化。
  • 看起来Observable&lt;boolean&gt; 仍然不在这里。如果数组中的第 n 个元素是第 n 个切换的状态,就像听起来一样,那么通过他们自己的主题推送各个更新:bool_subjects: Array&lt;BehaviorSubject&lt;bool&gt;&gt;。然后Observable.combineLatest(bool_subjects).map((bools) =&gt; bools.some(b =&gt; b)).
  • @concat 我没有看到你的评论,并发布了一个非常相似的答案,逐步完成了这个案例。
  • @PeterZhang 但是,在您的示例中,当您使用aSbj.next([Observable.of(true), ... 触发更改时,您实际上并没有在之前的Observable&lt;boolean&gt; 上发出新值,您只是发出了一个新的 Observable。您的真实用例如何?

标签: rxjs


【解决方案1】:

我希望,我不会误解您的问题。我认为,有这样一个主题存在一个大问题。这是带有行号的代码:

(1) const source1 = Observable.of(false);
(2) const source2 = Observable.of(false);

(3) const independentObservables = [source1, source2];

(4) const subject: Observable<Observable<boolean>[]> =
(5)   new BehaviorSubject(independentObservables);

问题在于source1source2 通常只创建一次,然后变成“静态流”。意思是,一旦它们被传递给Subject,它们就永远不会被其他流修改。因此,Subject 可能只产生一次事件,它反映了来自source1source2 的原始值。


在我的理解中应该做的不是(4), (5) 行,而是创建一个“监听”所有独立可观察对象的新可观察对象。它可能看起来像这样(使用combineLatest):

(6) const watchingObservable = Observable.combineLatest(...independentObservables);

然后你用它来map(产生一个聚合结果)或直接subscribe

(7) const aggregatedObservable: Observable<boolean> =
(8)   watchingObservable.map(values => values.some(Boolean));

(9) aggregatedObservable.subscribe( ... );

【讨论】:

  • @peter-zhang 这能回答你的问题吗?
  • 感谢您的回答!但是,它确实遗漏了我在原始问题中未能详细说明的一个细节。简单地在布尔 Observable 的静态列表上调用 Observable.combineLatest 是行不通的,因为列表会随着时间而改变。
  • @PeterZhang 哦,男孩。那是一个完全不同的问题! :(我什至创建了一个关于combineLatest()plnkr.co/edit/eQeRKHdF3Vm30EJ1raXh?p=preview的plunker
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
相关资源
最近更新 更多