在RxJS中使用管道运行的间隔会吗?

问题描述 投票:0回答:2

将在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构建的,其工作方式如下:

  • 每500ms发出一个迭代数(0,1,2,...)
  • 使用迭代编号从arr中提取值
  • 将提取的值发送给订阅了pipe方法结果的任何人
  • 当迭代次数大于arr.length时,停止发射迭代次数

因此,toRun.subscribe(val => val);将发出foo,然后在500毫秒bar之后将停止运行。尽管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)。

angular rxjs pipe intervals
2个回答
1
投票

您几乎完全理解它。一些注意事项:

  • 是,interval创建一个cold observable,仅在订阅时会产生数字。
  • pipe本身不会创建新的可观察值,pipe中的运算符会创建。
  • [maptake不会产生可观察到的高温,因此仍然很冷,只有在订阅时才会“运行”。
  • [interval最初等待500ms,然后发出foo(已订阅)]
  • 在给定的排放量之后,
  • take将取消其可观测的来源。这将导致链中的每个Observable取消订阅其来源,直到最终取消订阅interval。因此,它不再发出数字。

1
投票

您认为正确,您的代码应按预期工作,但看起来不应该使用RxJs。从运算符中获取封闭变量似乎是一个反对RxJ鼓励的无副作用纯度的危险信号。

[RxJ中有很多方法可以做某事;如果您开始考虑RxJS方式,那么您将找出正确的解决方案之一。就您而言,这两个技巧将带您朝正确的方向:

  • [只要有一个数组可以从中获取值,请考虑如何使用from, of之类的RxJs工具从中提取可观测对象>
  • 考虑如何组合多个可观察对象并使它们协调以产生正确的结果。
  • 用此代码替换您的toRun分配:

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

此解决方案是有关如何使用这两个技巧的简单但完美的示例。它更整洁,并且可能具有更好的性能。

在幕后,from将阵列变为可观察的,而zip使用可观察的间隔的频率来“调节”可观察的阵列的输出。您会在RxJ的工作方式中经常看到的典型模式。

注意:作为zip处理程序中使用subscribe的奖励。您不仅会获得时间间隔值,而且还会获得在数组参数中传递的相应数组值。

© www.soinside.com 2019 - 2024. All rights reserved.