作为业余爱好项目,我正在alternate futures and promises implementation基于"From Events to Futures and Promises and back"开展工作。原作者使用渠道/事件,这就是我使用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)
}
使用有效的Go语法,键入定义和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 :(得分:4)
Go
块与Go中的块不同。在core.async中,块作为附加到通道上的回调存在,因此只要通道本身存在,它们就会存在。因此,将go
块视为回调中的语法糖,并且所有明星都有意义。