RxJs:takeUntil 的奇怪行为?

RxJs : Weird behavior with takeUntil?

这里没什么太严肃的,只是好奇。
我想举个例子,想出了这段代码:

const { Observable, Subject } = Rx

const timeout$ = new Subject()

const obs$ = Observable
  .of(1)
  .takeUntil(timeout$)
  .delay(2000)
  .subscribe(x => console.log(x))

timeout$.next()
timeout$.complete()

我认为这段代码 不会 显示 console.log 但它会显示。

谁能解释一下为什么?
这是错误还是我对 takeUntil 的误解?

这是一个要演示的 Plunkr https://plnkr.co/edit/wpKztBabnBeIuNZS28wu?p=info

请注意,如果您调换 takeUntil()delay() 的顺序,它将不会按预期发出:

Observable
  .of(1)
  .delay(2000)
  .takeUntil(timeout$)
  .subscribe(x => console.log(x));

你看到的是因为 delay()takeUntil() 发送 complete 通知之前安排了发射。
现在在 RxJS 5.2.0 中 takeUntil() 运算符不会强制取消订阅它的源,这就是这里的问题。因此,当 takeUntil()timeout$ 通知时,它仍然订阅了它的源 Observable,因此来自 delay() 的计划发射不会被释放。

注意在处理来自通知 Observable 的发射时没有 this.unsubscribe() 调用:https://github.com/ReactiveX/rxjs/blob/master/src/operator/takeUntil.ts#L61

还有其他具有相同行为的运算符。例如 first()takeWhile().

另一方面,例如 take() 运营商取消订阅:

https://github.com/ReactiveX/rxjs/blob/master/src/operator/take.ts#L80

实际上已报告此行为,现在正在讨论这是否是错误: