2016-07-30 117 views
1

作爲一個業餘愛好項目,我正在根據"From Events to Futures and Promises and back"工作alternate futures and promises implementation。原作者在引擎蓋下使用頻道/事件,這就是爲什麼我使用core.async。未來的,在僞Go語法來表示,如下所示:如何處理無限循環

func future(func f() (T, bool)) Future <T> { 
    ch = newChannel() 
    spawn(func() { 
     x := f() 
     for { syncEvt(sndEvt(ch, x)) } 
    }) 
    return rcvEvt(ch) 
} 

使用有效圍棋語法,類型定義和get功能:

type Comp struct { 
    value interface{} 
    ok bool 
} 

type Future chan Comp 

func future(f func() (interface{}, bool)) Future { 
    future := make(chan Comp) 

    go func() { 
     v, o := f() 
     c := Comp{v, o} 
     for { 
      future <- c 
     } 
    }() 

    return future 
} 

func (ft Future) get() (interface{}, bool) { 
    c := <-ft 
    return c.value, c.ok 
} 

現在,當我端口這Clojure的,我是想實現它如下:

(defrecord Comp [value ok]) 

(defn future [f] 
    (let [future (chan)] 
    (go-loop [comp (f)] 
     (>! future comp) 
     (recur comp)) 
    future)) 

(defn get [future] 
    (<!! future)) 

由於我很新的Clojure(和core.async),我擔心無限go-loop。 IOC線程是否會被釋放?我是否應該提供某種毒丸來阻止循環(儘管我認爲這會很容易出錯)?有什麼建議麼?

+0

是的,通常是'recur'使用爲條件['if'](https://clojuredocs.org/clojure.core/if)或它的一個變種。 –

+0

我知道,但是從文章中的實現使用無限循環來確保未來(這是一個頻道)總是可用的,一旦'comp'變得可用。因此,我想知道如何在Clojure中處理這個問題。 – beatngu13

回答

4

Go Clojure中的塊不像他們在Go中。在core.async中,塊會作爲附加到通道上的回調來存在,因此只要通道本身存在,它們就會一直存在。所以想想go塊作爲語法糖而不是回調函數,它將全部變得有意義。

此視頻教程進入稍微詳細:https://www.youtube.com/watch?v=VrwVc-saWLw