RxJS 6不是无限的吗?

RxJS 6不是无限的吗?,rxjs,rxjs6,Rxjs,Rxjs6,我一直在玩RxJS来探索边缘,遇到了一些意想不到的事情 考虑以下代码: of(1) .pipe(expand(x => of(x + 1))) .subscribe( x => console.log(x), err => console.log(err), () => console.log('complete')); 当在节点中运行时,我希望这会产生一个无限的数字列表,每个数字增加1,当超过JavaScript中的最大数字时,最终会出错,

我一直在玩RxJS来探索边缘,遇到了一些意想不到的事情

考虑以下代码:

of(1)
.pipe(expand(x => of(x + 1)))
.subscribe(
    x => console.log(x), 
    err => console.log(err), 
    () => console.log('complete'));
当在节点中运行时,我希望这会产生一个无限的数字列表,每个数字增加1,当超过JavaScript中的最大数字时,最终会出错,或者我会用Ctrl-C(在Windows上)终止它。我没想到的是,在记录了不到1000个数字后,它会停止而不出错

我得到的是写入控制台的数字1-783

然后它停了下来

每一次

我负责。它停在783(这不是一个特殊的数字——256、1024等)。它不会记录错误或“完成”。它只是停止了

我本以为它会“永远”运行,抛出一个错误,或者至少“完成”注销。但它只是停止并将我返回到命令行

我做了一些挖掘,认为可能与可选的并发参数有关,该参数默认为
Number.POSITIVE_∞

但是,如果我显式地指定这个参数的值,我会得到同样奇怪的结果——即1的并发性会导致比1000000(回到783)、100多(~850)和200多(~840)的并发性值更多的值(始终是~860)。似乎大多数值都是在并发度为1时发出的,然后随着并发度的增加,它会慢慢下降到783个值。这就是说,我不知道是否实际上是并发性影响了这一点,尽管它看起来确实相关

我快速浏览了expand的源代码,没有看到任何可以解释这一点的东西

这不是我将在生产中运行的代码,但它激发了我的好奇心。有人有什么想法可以解释这一点吗

  • RxJS 6.3.2

  • 节点8.9.4

谢谢


TTE

这是预期的行为。我不确定您为什么没有从node.js收到任何错误消息,但实际上如下所示:

RangeError: Maximum call stack size exceeded
at SafeSubscriber.__tryOrUnsub (/Users/ojkwon/github/goj/node_modules/rxjs/internal/Subscriber.js:212:18)
...
简而言之,它遇到了堆栈溢出

调用
expand
时,返回通过的
创建的可观察对象,并通过expand操作符递归。RxV5及以上版本默认情况下,它的调度行为是
不调度任何内容
——这意味着,您创建了同步可观测对象,它再次创建同步堆栈,最终爆炸

您可以通过使用异步源或显式异步调度的给定值来进行无限扩展:即,如果您通过异步调度程序中的
扩展
来调度返回的可观察值,则可以进行无限扩展

const { of, asyncScheduler } = require('rxjs');
const { expand } = require('rxjs/operators');

of(1)
  .pipe(expand(x => of(x + 1, asyncScheduler)))
  .subscribe(
    x => console.log(x),
    err => console.log(err),
    () => console.log('complete'));

然后,您可以观察到运算符不会停止。

附加说明:它的行为已从v5更改,这意味着如果您尝试rxjs的v4中的类似代码段,您可能会注意到堆栈不会溢出,因为默认情况下,v4通过蹦床调度。我有点认为是这样的,但没有遇到错误让我有点失望。谢谢。非常感谢你的回答,终于有一刻Stackoverflow把我从堆栈溢出中救了出来。