F#可观察过滤器有副作用

时间:2012-10-13 15:47:55

标签: f# observable frp

我有许多事件被合并到一个执行某些命令的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执行两次,你能否建议另一种方法来实现相同的结果?我希望尽可能避免使用可变变量。

1 个答案:

答案 0 :(得分:2)

这个例子很好地说明了IObservable<'T>类型(在本例中通过Observable模块使用)和F#类型IEvent<'T>(以及Event模块中的函数之间的区别)。

当您使用 observables 时,每个订阅者都会创建一个新的操作链(因此每个订阅者都会执行一次副作用)。如果您使用事件,则状态将被共享,副作用仅执行一次(无论订阅者数量多少)。另一方面,当您从事件中删除所有订阅者时,事件不会被垃圾收集。

因此,如果您在删除所有订阅者时不需要删除事件,则只需使用Event代替Observable即可获得所需的行为:

modifyingevents 
|> Event.filter exec_action 
|> Event.scan (fun log action -> action::log) []