我有许多事件被合并到一个执行某些命令的observable中。如果命令成功,则会发生某些结果。此外,应记录该命令。
就代码而言,这看起来像
let mevts = modifyingevents |> Observable.filter exec_action
|> Observable.add (fun action -> self.OutlineEdited <- true)
其中函数exec_action
会导致一些副作用,例如编辑树视图。如果成功,则属性OutlineEdited
设置为true
。
我希望用
之类的东西来跟随它 mevts |> Observable.scan (fun log action -> action::log) []
但事实证明{em>每个订阅的观察者执行Observable.filter一次。这意味着副作用会重复。
如果没有exec_action
执行两次,你能否建议另一种方法来实现相同的结果?我希望尽可能避免使用可变变量。
答案 0 :(得分:2)
这个例子很好地说明了IObservable<'T>
类型(在本例中通过Observable
模块使用)和F#类型IEvent<'T>
(以及Event
模块中的函数之间的区别)。
当您使用 observables 时,每个订阅者都会创建一个新的操作链(因此每个订阅者都会执行一次副作用)。如果您使用事件,则状态将被共享,副作用仅执行一次(无论订阅者数量多少)。另一方面,当您从事件中删除所有订阅者时,事件不会被垃圾收集。
因此,如果您在删除所有订阅者时不需要删除事件,则只需使用Event
代替Observable
即可获得所需的行为:
modifyingevents
|> Event.filter exec_action
|> Event.scan (fun log action -> action::log) []