2012-10-13 29 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

完美運作!我想這引發了一個問題:如果我想要共享狀態的垃圾回收會怎麼樣。現在我不需要這個了,所以我想我會把它留給另一天。 –