RXJS 可观察移除管道操作员



我有一个问题,我想删除/添加任何以前添加的可观察量的运算符。

我得到了以下我无法改变的可观察性:

let objects$ = of([{
category: 1,
name: 'Some1'
}, {
category: 2,
name: 'Some2'
}]).pipe(
map(o => o.filter(b => b.category === 2))
)
objects$.subscribe(obj => console.log(obj));

此输出:按预期{category: 2,name: 'Some2'}

现在我想将过滤器的值更改为b.category === 1输出{category: 1,name: 'Some1'}

如果我执行以下操作:

objects$.pipe(
map(o => o.filter(b => b.category === 1))
)
objects$.subscribe(obj => console.log(obj));

我仍然得到{category: 2,name: 'Some2'}.

如果我这样做:

objects$ = objects$.pipe(
map(o => o.filter(b => b.category === 1))
)
objects$.subscribe(obj => console.log(obj));

我之所以[],是因为可观察量的输出不再具有类别 1。

我的问题是如何从原始可观察对象中删除.pipe()以添加新的?

无法删除运算符

通过使用pipe例如打电话给observable$.pipe( map(..) ),你并没有真正为observable$添加一些以后可以带走的东西,即使短语add operator X to your observable经常被安静地使用。

管道运算符是一个将可观察量作为其输入的函数 并返回另一个可观察量。这是一个纯粹的操作:以前的 可观察保持原样

const o1$ = of('1');
const o2$ = o1$.pipe(
map(x => x + '2'),
map(x => x + '3')
);

相当于

const o1$ = of('1');
const o2$ = map(x => x + '3')(
map(x => x + '2')(
o1$
)
);

你基本上是将纯函数调用与原始的可观察o1$作为输入,将其他一些可观察的作为输出。o1$不会更改,因此您必须将返回值分配给变量(o2$)以稍后使用或直接使用它以产生任何效果。

在上面的示例中,您可以重用o1$,并通过在o1$上使用不同的运算符来创建与o2$不同的可观察量。但是,您无法从o2$中删除用于定义o2$的函数调用。

您应该能够更改您关心的实现细节

如果你得到一个可观察的,你不能改变,你不应该关心它的具体实现,而只关心它发出什么。在这种情况下,可观察对象对您来说是一个黑匣子,据您所知只是发出{ category: 2, name: 'Some2' }.您不知道也不应该关心 Observable 在发出此值的过程中所做的特定事情。

但是您似乎知道并关心可观察对象在发出此值之前做了什么。如果你这样做了,你必须有一种办法让你(或同事)改变可观察量的实现。

动态注入代码

如果你的代码中,一个部分应该是固定的,而另一个部分应该是动态的,你可以定义一个高阶函数(固定部分),它接受另一个函数(动态部分)作为输入,并通过以下方式从一个原始可观察量创建不同的可观察量:

let getObjects$ = (predicate: (value: any) => boolean) => of([
{
category: 1,
name: "Some1"
},
{
category: 2,
name: "Some2"
}
]).pipe(map(o => o.filter(predicate)));
getObjects$(v => v.category === 1).subscribe(obj => console.log(obj));
getObjects$(v => v.category === 2).subscribe(obj => console.log(obj));

您在第一个操作中应用管道运算符 (objects$=>Observable.pipe())。 首次操作后,objects$内值为:

[{category: 2,name: 'Some2'}]

然后您的第二个操作将根据第一个(Observable.pipe(...).pipe(...))的结果完成。它不会更改objects$的值。 但是您再次订阅了初始可观察量(objects$=>Observable.pipe())。 第二个管道不会改变值,而是在应用运算符函数后返回新的Observablepipe

对于所需的结果:

let objects$ = of([
{
category: 1,
name: "Some1"
},
{
category: 2,
name: "Some2"
}
]);
objects$
.pipe(map(o => o.filter(b => b.category === 1)))
.subscribe(obj => console.log(obj));
objects$
.pipe(map(o => o.filter(b => b.category === 2)))
.subscribe(obj => console.log(obj));

最新更新