为什么 tap() 运算符 Rxjs 中的返回类型发生变化?

cha*_*ant 5 rxjs typescript

为什么tap运算符要改变 的类型someVar

根据定义,它不应该。

这会改变类型:

somevar = someObs$.pipe(
  tap(console.log)
)
Run Code Online (Sandbox Code Playgroud)

这不会:

somevar = someObs$.pipe(
  tap((v) => console.log(v))
)
Run Code Online (Sandbox Code Playgroud)

mon*_*ate 5

因为tap是一个副作用运算符。

这个运算符,如源代码注释所示:

当您想通过通知影响外部状态而不更改通知时使用

它不会改变您发出的值,但实际上可以让您接收该值并在可观察流之外对其执行某些操作。

与此同时,你可以对 Observable 流程做任何你想做的事情,这不会干扰你的副作用。

还。请注意,这someVar将是一个Observable,因为您没有订阅您的someObs$observable,而是实际上通过管道传递给它额外的运算符,这些运算符执行一些操作,然后将输出包装为 Observable 并返回该 Observable。

一个简单的例子是,当您尚未完成源可观察对象时,向用户执行加载器指示。

一个例子(不完整的):

let isLoading = false;

const somevar$ = someObs$.pipe(
    tap(v => this.isLoading = true), 
    filter(someFilter), 
    map(maybeSomeMapping))

somevar$.subscribe(finalValue => {
// maybe some extra code that you can actually write inside the same `tap` or even another `tap` which is more deep in the pipe chain.
this.isLoading = false; // resets the loader.
});
Run Code Online (Sandbox Code Playgroud)

您可能会问的一个问题是为什么?tap如果我可以在映射器运算符中简单地执行完全相同的副作用分配(例如:mapmergeMap等),为什么我需要一个运算符。

很简单,因为你会破坏映射的纯粹性。

您希望每个操作员都能完成其预期的任务。

Amap应该有映射逻辑并且不干扰其他任何东西。尽可能保持函数的纯粹性。如果你需要一些杂质,tap是你的朋友。