javascript - 在 RxJS Tap 中订阅对于异步逻辑来说是不好的做法吗?

标签 javascript rxjs

我有两个 http 请求,其中第二个请求(日志请求)应在第一个请求(订单请求)发出值后订阅,并且我执行了一些逻辑,不应被日志请求阻止并且日志请求的结果被忽略。

据我了解,点击是

Used to perform side-effects

https://rxjs.dev/api/operators/tap

并且由于我假设 Log 请求及其响应是 Order 请求的副作用,因此在 Tap 内订阅是一种不好的做法吗?有没有更灵活和 RxJS 的方法来处理这个问题?

const order = of('2- created order').pipe(
  delay(100),
  tap(console.log)
);

const log = of('4- logged info to log server').pipe(
  delay(500),
  tap(console.log)
);

console.log('1- started creating order');
order
  .pipe(tap(() => log.subscribe()))
  .subscribe(() => console.log("3- didn't wait for log server"));

StackBlitz

最佳答案

是的,这绝对是不好的做法。

你是对的,tap 存在副作用,但这些副作用不应该涉及其他流,它们应该是简单的副作用,例如分配变量或控制台日志记录等。

问题是,您通常不希望在 pipe 内部的 subscribe 内进行订阅,因为这样做会导致代码非常不可预测且难以维护。

例如,选项卡内的订阅看起来足够无害,但想象一下,如果您正在监听连续的数据流,您会有多少个订阅?您愿意跟踪它们全部取消订阅吗?这会不会变得很难理解/调试等等......

您的代码的问题在于,您在某种程度上以命令式方式思考(例如“执行此操作,然后执行此操作,然后...”),而不是从流的 Angular 进行思考。

所以基本上在我看来,而不是思考“在那之前我该怎么做?”您应该考虑如何处理流以及可以对其执行的操作的顺序。

就您而言,是否有任何原因希望在订阅内而不是在管道中打印第三条消息?

为什么不直接执行以下操作?

order
  .pipe(
    tap(() => console.log("3- didn't wait for log server")),
    switchMap(() => log)
  )
  .subscribe();

(就像这里:https://stackblitz.com/edit/rxjs-aace8i?file=index.ts)


如果可以的话,我想分析一下你的问题......

开始于

I am having two http requests where the second one (Log request) should be subscribed after the first one (Order request) emits a value

这似乎是一个简单的情况,具有初始可观察值(顺序)并需要使用映射运算符移动到不同的可观察值(日志),我假设您想要丢弃第一个并移动到第二个,所以我选择 switchMap (或者您可以使用 concatMapmergeMap)

然后我们就可以:

and I do some logic that should not be blocked by the Log request and the result of log request is ignored.

因为我们已经考虑过如何处理 2 个可观察量,所以如果我们阅读您的句子,它确实表明我们只想在第一个和第二个可观察量之间发生副作用,并且它无论如何都会忽略流的值,所以它显然需要一个简单的点击


对于这么长的消息我感到很抱歉,我希望它听起来不会太迂腐:P

我基本上想说的是,你应该始终查看你的流,并思考如何根据 rxjs 编程风格和你的需要将所有内容组合在一起,而不是某些做事方式是否可以接受,因为这让我真正意识到您已经怀疑这是否不是最佳解决方案。

关于javascript - 在 RxJS Tap 中订阅对于异步逻辑来说是不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67958700/

相关文章:

javascript - 如何对 rxjs5 进行单元测试?

javascript - 计算一个 DIV 中有多少个字符

javascript - Angularjs 中的电子邮件/ID 重复检查

javascript - 如何使用jquery获取元素的样式属性

javascript - .onkeypress 在 chrome 和 safari 中不起作用

javascript - 如何创建 bool 类型的 Observable?

angular - 如何在 ng-select 的 Observable 数组类型中插入值

javascript - 每 x 毫秒计算一个平均值

javascript - 如何在 JavaScript 中检测数组中的对象属于哪个类

javascript - RxJs:拖放示例:添加 mousedragstart