【问题标题】:How to explain that Observable.of(Math.random()) always returns the same value?如何解释 Observable.of(Math.random()) 总是返回相同的值?
【发布时间】:2020-01-24 17:59:40
【问题描述】:

我不确定如何解释。 of() 方法返回的 observable 不是多播。 如果我们这样做:

const obs = of(Math.random()).pipe(tap(()=>console.log('side effect'));
obs.subscribe(console.log);
obs.subscribe(console.log);
obs.subscribe(console.log);

我们会看到 3 个副作用,但 3 个也是相等的值。为什么?通常会在每次订阅时重新计算 observables。

例如

new Observable(observer => observer.next(Math.random()))

将返回 3 个不同的值。 为什么使用静态“of”方法创建的 observable 表现不同?我不知道该如何解释。和 observables 缓存有关系吗?

编辑 这是一个帮助我证明的小例子,'of' observables 确实是按需加载的。

const obs = of(undefined).pipe(
    map(() => Math.random())
);

甚至

const obs = of(Math.random).pipe(
    map(random => random())
);

【问题讨论】:

  • 这可能是因为您将调用Math.random() 的结果而不是函数本身传递给of 函数。
  • Math.random() 返回一个数字。当该数字“重新计算”时应该发生什么变化?
  • Math.random() 返回一个随机值并立即进行评估。所以of(Math.random()) 基本上就像of(0.123456) (或产生的任何随机值)。

标签: javascript caching rxjs


【解决方案1】:

如果你打电话给of(0.5),那么of 会看到你传递了 0.5 并基于它创建一个 observable。每个新订阅都会导致 observable 发出值 (0.5),然后完成。

如果您将其更改为 of(0.25 * 2),那么 of 仍然会看到您传递了 0.5,因此它的行为完全相同。在创建 0.5 之前确实进行了计算,但 of 对此一无所知。

如果您将其更改为 of(Math.random()) 并且偶然计算的值为 0.5,则行为再次完全相同。 of 传递了 0.5,因此它创建了一个输出 0.5 然后完成的 observable。它不知道 0.5 是如何计算出来的。

【讨论】:

  • 我不确定我是否理解您的回答。但我认为他只是在寻找defer。看我的回答
【解决方案2】:

在读取代码时会准备好传递给of 的值。这只是一个与 RxJs 无关的 JS 东西。即使你不订阅 observable。例如:

const MyMathRandom = () => {
  console.log('MyMathRandom has been run');
  return Math.random();
}

const test = of(MyMathRandom())

将在控制台中显示MyMathRandom has been run

在您的情况下,您希望 lazily 执行函数,并且有一个运算符:defer

如果您将代码更新为:

const source = defer(() => of(Math.random()))

source.subscribe(x => console.log(x));
source.subscribe(x => console.log(x));
source.subscribe(x => console.log(x));

输出将是您要查找的内容。例如:

0.20757387233599833
0.6417609881625241
0.09756371489129778

现场演示:https://stackblitz.com/edit/rxjs-jymadr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多