问题标签 [rxjs-pipeable-operators]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
angular - 如何在管道内调用 forkJoin?
TL;DR 是否可以在 observable 的管道内使用 forkJoin?
全文:我有一个服务,它返回 Observable 对象数组。对于这些对象中的每一个,我都需要再次调用返回可观察对象的服务,并对每个结果应用另一个操作。
我目前的解决方案是这样的:
我想摆脱第一个订阅并改用管道。问题是 forkJoin 的教程将其显示为对象或数组被传递到的源,而不是管道的一部分。
从地图内部调用 forkJoin
返回Observable<Observable<resolved forkJoin arguments>>
我可能需要递归订阅。好像不是什么好办法。
将 fJ 放入不带参数的管道中
以可观察物的奇怪纠结结构结束。这似乎也不是一个好办法。
甚至可以从管道内部使用 forkJoin 吗?
angular - 为 takeUntil 运算符提供的杀死 observable 的更好方法是什么,为什么?
我有一个关于使用 Angular 和 RxJs 的 takeUntil 运算符取消订阅的常见模式之一的问题。在这篇文章中,它在第三个位置。例如,我们在组件类中有这样的代码:
第一行 this.destroy$.next(true) 是完全清楚的。但第二个不是。如果我们研究这些方法的实现,我们会发现它们的行为有些相似。 完成(): 取消订阅():
据我了解,在语义上 complete() 更可取,因为我们在组件生命周期中第一次和最后一次调用 next(),然后我们完成了这个 Subject,将其视为 Observable 并可以调用 complete()。这些方法属于观察者,取消订阅属于可观察对象,我们没有要取消订阅的订阅。但在底层,这些方法有类似的代码:
理论上,complete() 具有延迟效果,因为它可能会在每个订阅的观察者上调用 complete(),但我们在 destroy$ 上没有观察者。那么问题来了——哪种方式更可取,更不容易出错,为什么?
rxjs - 使用可管道运算符时,我可以跟踪值吗?
有没有办法通过可管道操作符来跟踪值?
举一个具体的例子,假设我想:
在数据流S上:
- 记忆S当前数据
- 发出 HTTP 请求
- 对响应做一些事情
- 使用操作结果发出另一个 HTTP 请求
- 创建一个包含基于1的值和响应的对象
然后合并这些并利用我创建的对象。
基本上,
任何有关此事的意见将不胜感激。
注意:如果可能的话,我不希望通过在顶部创建一个对象来携带我需要的值。
javascript - 具有原始顺序的 RxJS mergeMap()
抽象的问题
有什么方法可以mergeMap
按照外部 observable 的原始顺序消耗 a 的结果,同时仍然允许内部 observable 并行运行?
更详细的解释
让我们看一下两个合并映射运算符:
-
...它需要一个映射回调,以及可以同时运行的内部可观察对象的数量:
在此处查看实际操作:https ://codepen.io/JosephSilber/pen/YzwVYNb?editors=1010
这将分别触发
1
、2
和的 3 个并行请求3
。一旦其中一个请求完成,它将触发另一个请求4
。以此类推,始终保持 3 个并发请求,直到处理完所有值。但是,由于先前的请求可能在后续请求之前完成,因此产生的值可能是无序的。所以而不是:
...我们实际上可能会得到:
-
...输入
concatMap
。该运算符确保所有可观察对象都按原始顺序连接,因此:...将始终产生:
在这里查看它:https ://codepen.io/JosephSilber/pen/OJMmzpy?editors=1010
这是我们想要的,但现在请求不会并行运行。正如文档所说:
concatMap
等价于mergeMap
参数concurrency
设置为1
。
回到问题:是否有可能获得 的好处mergeMap
,即可以并行运行给定数量的请求,同时仍然以原始顺序发出映射值?
我的具体问题
上面抽象地描述了这个问题。当您知道手头的实际问题时,有时会更容易推理问题,所以这里是:
我有一份必须发货的订单清单:
我有一种
shipOrder
实际发送订单的方法。它返回一个Promise
:API 最多只能同时处理 5 个订单发货,所以我
mergeMap
用来处理:订单发货后,我们需要打印其发货标签。我有一个
printShippingLabel
功能,给定发货订单的订单号,将打印其发货标签。所以我订阅了我们的 observable,并在输入值时打印运输标签:这可行,但现在运输标签打印乱序,因为
mergeMap
根据何时shipOrder
完成其请求发出值。我想要的是标签以与原始列表相同的顺序打印。
那可能吗?
可视化
有关问题的可视化,请参见此处:https ://codepen.io/JosephSilber/pen/YzwVYZb?editors=1010
您可以看到较早的订单在后续订单发货之前就已打印。
angular - 当我稍后使用 `tap` 方法时,不会调用 `map`。我从水龙头得到回报
我在tap
之前的响应中做了一些更正,但在实施之后map
我没有被调用。一点也不安慰我。map
tap
map
在我们发送给map
任何人帮助我之前,在回复中进行一些更正的最佳方法是什么?
以及让我知道tap
这里的确切用途。这是我的代码:
提前致谢。
angular - 如何根据源值应用 rxjs 运算符?
我正在创建一个包含多个表单的页面,并且我想检测每个表单上的 mousedown、focus 和 blur 事件。
大多数时候,它们是同时发出的(例如,在已经选择另一个表单时单击一个表单,发出“blur”和“mousedown”)。目标是只处理其中一个。
我创建了一个名为interactions$ 的Observable,它发出的值是“事件”对象,例如mousedown、focus 或blur 事件。
我在那个 Observable 上使用管道,现在我有两个操作员选项:
- debounceTime(100) 以便只处理最后一个
- throttleTime(100) 以便只处理其中的第一个。
理想情况下,我希望在 blur 事件上同时处理 mousedown 和 focus 事件,但问题是当交互 $ 发出时:
- “mousedown”在“blur”之前发出
- 在“模糊”之后发出“焦点”
所以,我的问题是:
有没有办法根据源值应用 debounceTime() 或 throttleTime() ?
编辑:
此交互 $ 是一个主题,其值正在此事件处理程序上发出:
其中 FormFieldInteraction 只是一个具有 2 个字符串属性的类。
编辑2:
基本上我想要这样的东西,但我不确定是否有任何 rxjs 运算符:
angular - 为什么过滤器运算符的参数没有采用可观察数组中存在的属性
我正在尝试过滤来自可观察对象的数组,如果属性“start”是日期字符串与另一个日期字符串匹配,但在过滤器运算符函数中,参数未将“start”识别为有效属性
我已经阅读了多个示例,并且与我的比较似乎是一个非常相似的场景
当我订阅这个 observable 时在另一个文件上
预期输出应为:{ idAuction: '4', start: '2019-07-19T15:30', },
但没有编译它声明 .start 不是 aucs 的有效属性
angular - Angular 链式方法中的异常处理?
我有一个简单的问题,我认为 Angular 专家很容易回答。
我有如下方法:
我在一种方法中链接了 3 种方法:
convertFileFromFilePathToBlob
convertBlobToFormData
postImageToServer
所有 3 种方法都可以在任何故障点引发/发出错误。我的问题是关于在这种情况下如何进行异常处理?
我目前的实现,只有一个catchError
就可以了吗?如果没问题,如果任何链接方法引发错误,它会被执行吗?
或者
我是否需要catchError
在每种方法之后使用多个运算符来捕获其错误?如果是,我不知道我该怎么做?
有人可以解释在这种情况下我应该如何处理错误吗?
javascript - rxjs 运算符,在回调之前和之后添加日志记录
我试图把这个:
进入一个接受回调() => someCallback()
并在其前后添加日志记录副作用的新运算符。当我只使用显式版本时,我的日志功能使用performance.now()
并且它们按预期工作* tap
,但我的操作员都没有做同样的事情。
预期成绩
使用我的运营商的管道:
应生成如下所示的日志:
但是我得到了这个:
通过查看时间戳,我可以看到end
日志的时间戳是正确的,但是begin
那些为时过早。
我尝试过defer
以不同的方式使用,但结果没有改变。
我试过的
我试过用一个defer
或只是开始记录过程来包装整个管道,或者做of(null).pipe
然后把所有的效果放在一起。我什至尝试过根本不使用defer
,只返回一个以 . 开头的管道null
。没有任何东西产生期望的行为。