我正在使用一个库,它将结果作为双轨值(成功和失败)。Observable.map
函数体我经常从函数的成功跟踪中得到可观察的结果,但我不知道如何处理它们(在Observable.map
body).
换句话说,我经常陷入结果如下所示的情况(当然这是最简单的):
Rop.Result<IObservable<Rop.Result<IObservable,Messages>,Messages>
一方面,将消息转换回异常并引发它们似乎对我来说很重要,另一方面,错误处理程序是不纯的函数,我宁愿不传递它们。
我想知道处理双轨结果失败的标准和干净的解决方案是什么Observable.map
body.
更新:示例
这是该问题最简单的示例:
module problem
open FSharp.Control.Reactive
type Person = {FirstName:string;LastName:string}
let getPersonByLastName lastName =
let persons = Observable.toObservable<|seq{
yield {FirstName="Jhone";LastName="Smith"}
yield {FirstName="Joe";LastName="Smith"}
yield {FirstName="Jack";LastName="Smith"}
}
Rop.succeed persons
let main =
let final =
Observable.single("Smith")
|>Observable.map(fun lastName ->
let personResults = getPersonByLastName lastName
personResults
)
0
在这个例子中final
表达式的结果是类型IObservable<Result<IObservable<Person>,ErrorMessage list>>
但我希望它是IObservable<Person>
,因为进一步Observable
转换最终会得到非常肮脏和复杂的表达式。
在最简单的层面上,您需要的是一种提取然后呈现的方法IObservable
包裹在一个RopResult
。评论中已经提到了解决方案的一部分(Observable.bind
),另一个是函数RopResult<IObservable<'a>, 'b> -> IObservable<RopResult<'a,'b>>
.
为此,您需要解构RopResult
并处理这两种情况。因此,将其放在您所说的问题的背景下:
Observable.single("Smith")
|>Observable.bind(fun lastName ->
match getPersonByLastName lastName with
| Rop.RopResult.Success (next, msgs) ->
next |> Observable.map (fun x -> Rop.RopResult.Success (x, msgs))
| Rop.RopResult.Failure msgs ->
Observable.result <| Rop.RopResult.Failure msgs)
这是好的代码吗?我不这么认为。您可以通过使用其他 ROP api 函数,或者通过在此处使用绑定主体的计算表达式来使其稍微好一点,但这不是重点。
使用 Observables 的反应式编程和“面向铁路的编程”都是有用的工具,只要它们能够捕获和抽象出您正在建模的任何计算中涉及的一些复杂元素。这是可行的,因为它们是建立在可以很好地组合在一起的基元之上的。当您尝试像这样“交织”两者时,您会失去一些,因为您必须自己管理该构图。
我会说你最好使用异常 https://eiriktsarpalis.wordpress.com/2017/02/19/youre-better-off-using-exceptions这里 - 特别是因为 Observables 对它们有内置的支持。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)