将在 RxJS 中通过管道传输 运行 的间隔吗?

Will an interval which got piped run in RxJS?

在 RxJS 中 运行 的间隔会被管道化吗?

这就是我的意思。假设我们有以下代码:

const arr = ["foo", "bar"];
const i = interval(500);
const toRun = i.pipe(
    map(index => arr[index]),
    take(arr.length)
);
toRun.subscribe(val => val);

我理解正确吗,代码的工作原理如下:

1 i 已创建,但在我们订阅它之前不会是 运行。

2 在 pipe 方法的帮助下,我们创建了一个新的 Observable,它建立在 i 的基础上,工作方式如下:

因此,toRun.subscribe(val => val); 将发出 foo,然后在 500 毫秒后 bar 将停止 运行ning。虽然 i 永远不会发出任何东西,因为没有人订阅它。

我想了解这是如何工作的,所以,如果我错了,请更正我的解释以回答我的问题。

我在阅读 Angular 文档时偶然发现了其他问题。更具体地说是通过 async pipe。我在那里遇到了以下示例:

import { Component } from '@angular/core';
import { Observable, interval } from 'rxjs';
import { map, take } from 'rxjs/operators';

@Component({
  selector: 'app-hero-message',
  template: `
    <h2>Async Hero Message and AsyncPipe</h2>
    <p>Message: {{ message$ | async }}</p>
    <button (click)="resend()">Resend</button>`,
})
export class HeroAsyncMessageComponent {
  message$: Observable<string>;

  private messages = [
    'You are my hero!',
    'You are the best hero!',
    'Will you be my hero?'
  ];

  constructor() { this.resend(); }

  resend() {
    this.message$ = interval(500).pipe(
      map(i => this.messages[i]),
      take(this.messages.length)
    );
  }
}

而且我很好奇是否由于 interval(500) 的不必要 运行 可能会出现性能问题(因为 pipe 将创建一个新的可观察对象并且 interval(500) 不会被显式使用,而只能在新的可观察对象创建期间被 pipe 使用。

你理解的差不多了。一些注意事项:

  • 是的,interval 创建了一个 cold observable,它只会在订阅时生成数字。
  • pipe 本身不会创建新的可观察对象,pipe 中的运算符会。
  • maptake 不会使 observable 变热,所以它仍然很冷,只有在订阅时才会 "run"。
  • interval 最初等待 500 毫秒,然后发出 foo(订阅后)
  • take 将在给定的排放量后取消订阅其可观察到的来源。这将导致链中的每个 Observable 取消订阅其源,直到最终 interval 将被取消订阅。所以它不再发出数字。

您的想法是正确的,您的代码应该按预期工作,但它看起来不像应该使用 RxJs 的方式。从运算符内部访问闭包变量似乎是反对 RxJs 鼓励的无副作用纯度的危险信号。

在 RxJs 中有很多方法可以做某事;如果您开始以 RxJS 的方式思考,那么您将找到一种正确的解决方案。对于您的情况,这两个提示将带您走向正确的方向:

  • 只要有数组可以从中获取值,请考虑如何使用 from, of
  • 等 RxJs 工具从中提取可观察值
  • 想一想如何组合多个可观察值并让它们协调以产生正确的结果。

用此代码替换您的 toRun 作业:

 import {from, interval, zip} from "rxjs";
 // ...
 const toRun = zip(from(arr),i);  // where i is interval(500)

此解决方案是一个简单但完美的示例,说明了如何使用这两个技巧。它更简洁,而且性能可能更好。

在幕后,from 将数组变成一个可观察对象,而 zip 使用间隔可观察对象的频率到 "moderate" 数组可观察对象的输出。 Observables 像这样交互是一种典型的模式,您会在 RxJs 的工作方式中经常看到。

注意:作为在 subscribe 处理程序中使用 zip 的奖励。你不仅会得到间隔值,还会得到相应的数组值,这些值是在数组参数中传递的。