2012-10-13 23 views
1

我有许多事件被合并到一个执行一些命令的observable中。如果命令成功,则会发生一些结果。另外,该命令应该被记录下来。带有副作用的F#可观察过滤器

在代码而言,这看起来像

let mevts = modifyingevents |> Observable.filter exec_action 
        |> Observable.add (fun action -> self.OutlineEdited <- true) 

其中函数exec_action导致某些副作用如编辑一个TreeView。如果这成功,则财产OutlineEdited被设置为true

我希望的东西按照这个像

mevts |> Observable.scan (fun log action -> action::log) [] 

,但事实证明,Observable.filter每个订阅观察者执行一次。这意味着副作用将会重复。

您能不能建议另一种方式来达到相同的结果,而不是exec_action执行两次?如果可能,我希望避免使用可变变量。

+1

你可以有'exec_action'操作在内部使用'lazy',这样评估只发生在第一次执行时。 – ildjarn

回答

2

这个例子很好地ilustrates的IObservable<'T>类型(经由Observable模块在该实施例中使用)和(在Event模块和功能)的F#类型IEvent<'T>之间的差。

当您使用观测值时,每个用户都会创建一个新的操作链(因此对每个用户执行一次副作用)。如果您使用事件那么状态将被共享,副作用只会执行一次(无论用户数量是多少)。另一方面,当您从事件中删除所有用户时,事件不会被垃圾收集。

所以,如果你不需要的事件时,所有订户被删除到被删除,你应该得到的行为,你只想使用Event代替Observable

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

完美运作!我想这引发了一个问题:如果我想要共享状态的垃圾回收会怎么样。现在我不需要这个了,所以我想我会把它留给另一天。 –