rxjs中Observable.lift和Observable.pipe有什么区别?

Geo*_*ell 9 javascript rxjs angular

文档定义Observable.lift(operator: Operator)为:

创建一个新的Observable,将此Observable作为源,并将传递的运算符定义为新的observable的运算符.

Observable.pipe(operations: ...*)作为:

用于将功能操作符拼接成链.返回按传递顺序调用的所有运算符的Observable结果.

所以显然.pipe可以接受多个运营商,而.lift不是.但pipe也可以接受单个运营商,因此这不可能是唯一的区别.仅从文档来看,我不清楚它们是什么以及它们存在的原因.有人可以解释一下这些功能的用途,以及何时应该使用它们?


到目前为止的观察

以下代码(typescript):

let myObservable = Observable.of(1, 2, 3);
let timesByTwoPiped = myObservable.pipe(map(n => n * 2));
let timesByTwoLift = myObservable.lift(new TimesByTwoOperator());

timesByTwoPiped.subscribe(a => console.log('pipe:' + a));
timesByTwoLift.subscribe(a => console.log('lift:' + a));
Run Code Online (Sandbox Code Playgroud)

并且TimesByTwoOperator:

class TimesByTwoOperator implements Operator<number, number> {
  call(subscriber: Subscriber<number>, source: Observable<number>): void | Function | AnonymousSubscription {
    source.subscribe(n => {
      subscriber.next(n * 2);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

似乎使用.lift和两者来实现相同的结果.pipe.这个实验表明,我认为升降机和管道都可以用来实现相同的目的是正确的,尽管在这种情况下管道版本更简洁.

由于Operator传入的类型.lift被赋予对源可观察和订阅的完全访问权限,因此可以实现强大的功能; 例如保持状态.但我知道也可以通过.pipe例如buffer操作员实现相同的功率.

我仍然不清楚为什么它们都存在以及各自的设计目标.

JHe*_*eut 9

我在这里找到了关于这个主题的深入讨论以及删除 Observable.lift 以支持 Observable.pipe 的潜在想法:https : //github.com/ReactiveX/rxjs/issues/2911

TL; 博士

现在让我们比较“纯”提升和管道签名:

// I'm intentionally ignoring pipe's multiple operator function args,
// since we could redefine lift to also take multiple operator functions
type Operator = <T, R>(sink: Observer<R>) => Observer<T>
type lift = <T, R>(src: Observable<T>, op: Operator) => Observable<R>;
type pipe = <T, R>(op: Operator) => (src: Observable<T>) => Observable<R>
Run Code Online (Sandbox Code Playgroud)
  • pipe 的操作符函数将 Observable 映射到 Observable
  • Lift 的 operator 函数将 Observer 映射到 Observer

这只是表示以下任一想法的另一种方式:

  • 构建一个从源到接收器的 Observable 链
  • 或者构建一个从接收器到源的观察者链


Rea*_*lar 7

有人可以解释一下这些功能的用途,以及应该在什么时候使用它们吗?

lift()创建一个新的可观察对象,但pipe()没有。pipe()遵循函数式编程范式并且lift()是面向对象的。

它们都接受函数作为输入参数,但优点pipe()是没有创建额外的 observable。

当您使用lift()一个单一的运营商被连接到一个新的观察到的,当这个新的观察到所预订的连接运营商拦截它订阅太前的数据流。

这与pipe()工作方式不同,因为运算符返回相同的可观察量不会对原始可观察量产生任何更改。

pipe()之后引入lift(),我认为这是链接运营商的首选方式。