RXJS Observable 移除管道操作符

Luk*_*oon 5 observable rxjs angular

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

我得到了以下我无法更改的可观察对象:

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));
Run Code Online (Sandbox Code Playgroud)

这输出:{category: 2,name: 'Some2'}正如预期的那样。

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

如果我执行以下操作:

objects$.pipe(
      map(o => o.filter(b => b.category === 1))
    )
    objects$.subscribe(obj => console.log(obj));
Run Code Online (Sandbox Code Playgroud)

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

如果我做:

objects$ = objects$.pipe(
      map(o => o.filter(b => b.category === 1))
    )
    objects$.subscribe(obj => console.log(obj));
Run Code Online (Sandbox Code Playgroud)

我得到,[]因为可观察的输出不再有类别 1。

我的问题是如何.pipe()从原始 observable 中删除以添加新的 observable ?

fri*_*doo 3

您无法删除运算符

通过使用pipe例如calling,你并没有真正添加一些可以稍后删除的observable$.pipe( map(..) )东西,即使这个短语经常被使用。observable$add operator X to your observable

Pipeable Operator 是一个将一个 Observable 作为输入并返回另一个 Observable 的函数。这是一个纯粹的操作:之前的 Observable 保持不变

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

相当于

const o1$ = of('1');
const o2$ = map(x => x + '3')(
  map(x => x + '2')(
    o1$
  )
);
Run Code Online (Sandbox Code Playgroud)

您基本上将纯函数调用与原始 Observableo1$作为输入和其他一些 Observable 作为输出链接起来。o1$不会更改,因此您必须将返回值分配给变量 ( o2$) 以便稍后使用或直接使用它才能产生任何效果。

在上面的示例中,您可以重用o1$并创建不同的 Observable,而不是o2$在 上使用不同的运算符o1$。但是,您无法删除用于定义的函数o2$调用o2$

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

如果给你一个 Observable,你无法更改,那么你不应该关心它的具体实现,而只关心它发出的内容。在这种情况下,Observable 对你来说是一个黑匣子,据你所知,它只是发出{ category: 2, name: 'Some2' }。你不知道也不应该关心 Observable 在发出这个值的过程中所做的具体事情。

但你似乎知道并关心 Observable 在发出这个值之前做了什么。如果你这样做,你(或同事)必须有一种方法来改变 Observable 的实现。

动态注入代码

如果您的代码的一部分应该是固定的,而另一部分应该是动态的,您可以定义一个高阶函数(固定部分),它接受另一个函数(动态部分)作为输入,并通过这种方式从一个原始 Observable 创建不同的 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));
Run Code Online (Sandbox Code Playgroud)