rxjs - 在 RxJS 中何时使用 tap() 以及何时使用 map()
问题描述
该文档使用以下代码描述了 tap():
import { fromEvent } from 'rxjs';
import { tap, map } from 'rxjs/operators';
const clicks = fromEvent(document, 'click');
const positions = clicks.pipe(
tap(ev => console.log(ev)),
map(ev => ev.clientX),
);
positions.subscribe(x => console.log(x));
但我不明白为什么要使用水龙头。难道只是记录。解释说
将每次点击映射到该点击的 clientX 位置,同时记录点击事件
解决方案
对源 Observable 上的每个发射执行副作用,但返回与源相同的 Observable
例子:
tap(value => console.log(value))
将给定的项目函数应用于源 Observable 发出的每个值,并将结果值作为 Observable 发出。
例子:
map(value => 'prefix' + value)
为什么不使用 map 或其他运算符来处理 log 等副作用
您可以使用 map、scan 和任何其他获取函数并返回单个结果的运算符来实现副作用。这将使您的代码将来很难理解/调试/查找错误。前提是,通常在管道中使用副作用是不好的。如果您需要/想要它并且不希望每个日志记录点都有很多订阅,那么日志记录可能是一个例外。因此,点击可能很有用。您可以将其调整为以下步骤:
- 尽量避免副作用
- 如果您需要一些(记录),请使用点击来澄清有副作用
你可以但不应该怎么做的例子
switchMap(value => {
console.log(value); // Side effect 1
const newValue = foo(value);
console.log(newValue); // Side effect 2
return of(newValue);
})
你可以怎么做和应该怎么做的例子
tap(console.log), // Side effect 1
switchMap(value => of(foo(value))),
tap(console.log) // Side effect 2
最后一句话:当您最初编写的代码并没有带来太多好处时。你的项目越大,当其他人试图找到错误时,它会大大节省时间。
推荐阅读
- java - 如何从 JWT 令牌身份验证中获取声明值
- powerbuilder - 查询 Powerbuilder 以获取某些复选框并输入 text/singelineedit 以获取 showig 消息框
- c++ - 如何将 crc-32 修改为 crc-32/mpeg-2
- scala - Play 2.5.x 中是否有用于捕获请求和响应以进行自定义日志记录的插件?
- c# - .Net Core 2.1 是否支持 HTTP/2 请求?
- java - 动画完成后如何设置图像可见性
- reactjs - 使用 firebase-functions 部署基于反应的 SSR 应用程序时出错
- sapui5 - 标签未左对齐
- javascript - React - 映射数组对象并传递给 react-select 中的 options 属性
- laravel - Laravel php 单元测试在 Windows Docker 中需要很长时间