【问题标题】:Observables BasicsObservables 基础知识
【发布时间】:2017-12-26 23:33:17
【问题描述】:

我相信我有一个适用于 Observables 的用例,但我不确定如何实现,因为 Observables 不是最直观的概念。 假设我有 3 个号码:let a: number, b: number, c: number;,我想在它们发生变化时对其进行监控。 if((a + b + c) / 3 === 0)) return true else false。如何创建一个观察者来监控这些数字并使用它我可以获得boolean 值?

【问题讨论】:

  • 这些连评论都投反对票的怪物是谁?
  • 您定义了 4 个流(observables):1 个用于每个单独的变量,1 个将它们的值组合到该表达式中。如果您想自学,请查看learnrxjs.io
  • 这和角度有什么关系?
  • 出于可悲的原因,拒绝投票是匿名的。许多通常乐于助人的人在发起投票、煽动等战争时遇到过不好的经历。我们感谢评论投票的原因,但政策并不要求这样做。
  • 投反对票的可能原因:没有概括问题的无意义标题;还没有表现出任何解决问题的努力。

标签: javascript rxjs


【解决方案1】:

这是一个例子。在现实生活中,aSubjectbSubjectcSubject 是常规的 Observable 流,您可以构建,也可以从您的框架或选择等中获取。

在我的演示中,我使用BehaviorSubjects,因为从技术上讲,SubjectsObservables

代码的Setup部分创建三个源流,formulaObservable 检查最后一个已知值的总和是否abc、除以30。请注意,aSubject.next(1) 在某种意义上与“普通”JS 中的a = 1 有点相似。主要区别在于.next() 在 Observable 流中创建了一个 even

combineLatest() 运算符创建一个新的 Observable,它查看 n 个输入 Observable 流并计算这 n 个流的最后一个已知值的一些函数。

import { Observable, BehaviorSubject } from 'rxjs';

// "Setup"

const aSubject = new BehaviorSubject<number | undefined>(undefined);
const bSubject = new BehaviorSubject<number | undefined>(undefined);
const cSubject = new BehaviorSubject<number | undefined>(undefined);

const formulaObservable = Observable
  .combineLatest(
    aSubject,
    bSubject,
    cSubject,
  )
  .map(values => {
    const [a, b, c] = values;
    if (a == null || b == null || c == null) {
      return Observable.never();
    } else {
      return (a + b + c) / 3 === 0;
    }
  });

formulaObservable.subscribe(result => console.warn(`Result: ${result}`));

// ---
// "Usage"

aSubject.next(1);
bSubject.next(2);
cSubject.next(1); // a===1, b===2,         c===1,         formulaObservable==Observable.of(false)
bSubject.next(1); // a===1, b===1,         c===1,         formulaObservable==Observable.of(true)

希望,它会有所帮助。


附:您可以使用交互式RxJsMarbles 来了解它们如何更好地工作。请注意,彩色球是可拖动的。

P.P.S.这是一个不错的问题,但我认为您的反对意见要么是因为您没有进行研究(没有随问题本身发布代码),要么是因为您没有在 * 上进行搜索。

【讨论】:

  • @Zachscs 是的,np
  • 你在这里构造了一个有点奇怪的流,因为结果类型是Observable&lt;boolean | Observable&lt;any&gt;&gt;。如果您不想在空输入上发出,您应该filter 他们。
  • 这很好,基本上将map 分解为filter 然后map,大大简化了。
  • 好答案!
  • 有很多方法可以实现 OP 的要求,我只是展示 a 方法。是的,我会在有时间的时候完善细节。