将在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
构建的,其工作方式如下:
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
)。
您几乎完全理解它。一些注意事项:
interval
创建一个cold observable,仅在订阅时会产生数字。 pipe
本身不会创建新的可观察值,pipe
中的运算符会创建。 map
和take
不会产生可观察到的高温,因此仍然很冷,只有在订阅时才会“运行”。interval
最初等待500ms,然后发出foo
(已订阅)]take
将取消其可观测的来源。这将导致链中的每个Observable取消订阅其来源,直到最终取消订阅interval
。因此,它不再发出数字。您认为正确,您的代码应按预期工作,但看起来不应该使用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
的奖励。您不仅会获得时间间隔值,而且还会获得在数组参数中传递的相应数组值。