TypeScript/RXJS - lastValueFrom 意外行为

TypeScript/RXJS - lastValueFrom unexpected behaviour

我是 rxjs 的初学者,正在测试订阅功能。当它发出值时,我决定订阅 observable 本身。当 lastValueFrom(x1$); 放在同一个地方或被注释掉时,控制台上不会显示任何输出。在我看来这是意料之中的,因为我不应该在那里订阅(我很欣赏一个合乎逻辑的解释,因为我不知道为什么)。但是,当 lastValueFrom(x1$); 放在 初始化 observable 之后,代码执行超过 1000 次然后停止。我不确定为什么不发生什么事。这是片段:

import { Observable,  lastValueFrom} from "rxjs";

class LastValueFromExample {
    constructor() {
        let x1$: Observable<number>;
        console.log("===Start===");
        let i = 0;
        x1$ = new Observable((channel) => {
            i++;
            channel.next(Math.random());
            x1$.subscribe((x) => { console.log(`${i} value: ${x}`); });//subscribed here
        });
        lastValueFrom(x1$);//comment this and no values will be printed
        console.log("===End===");
    }
}

let lvfe: LastValueFromExample = new LastValueFromExample();

您正在使用 Observable 创建一个无限循环。 每当 x1$ 被订阅时,你都会再次订阅它,因为 Observable 构造函数中的回调被调用,它本身包含一个订阅函数。

注释掉 lastValueFrom(x1$) 时没有任何反应的原因是 lastValueFrom(x1$) 订阅了可观察对象,但从未完成,因为 x1$ 从未完成。


编辑:您可以使用以下方法在构造函数中完成可观察对象:

  channel.complete();

如果您想在值发生时查看值,我建议您使用 tap 运算符。

const {
  from,
  of ,
  Observable,
  lastValueFrom,
  tap
} = rxjs;



class LastValueFromExample {
  constructor() {
    let x1$;
    console.log("===Start===");
    let i = 0;
    x1$ = new Observable((channel) => {
      i++;
      channel.next(Math.random());
    }).pipe(tap({
      next: (x) => {
        console.log(`${i} value: ${x}`)
      },
      // Note: this never runs.
      complete: (x) => {
        console.log(`Subscription completed with ${x}`)
      }
    }));
    // First subscription
    x1$.subscribe(); //subscribed here
    // Second subscription
    lastValueFrom(x1$); //comment this and no values will be printed
    console.log("===End===");
  }
}

let lvfe = new LastValueFromExample();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.5/rxjs.umd.min.js" integrity="sha512-f9/zRLfT4GaHBAniWJeFTsViOGP3hBxfEhecIauTbM5Ad51sTb4AoFJV5VbFl+Q7PClIU4kNHInGwhWFZKqE9Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>