Pie*_*Pah 10 asynchronous channel go promise
我正在尝试在Go中实现Promise,这与Javascript中的类似.
type Promise struct {
Result chan string
Error chan error
}
func NewPromise() (*Promise) {
r := make(chan string, 1)
e := make(chan error, 1)
return &Promise{
Result: r,
Error: e,
}
}
func main() {
var p = NewPromise()
go func(p *Promise) {
time.Sleep(time.Duration(5)*time.Second)
p.Result <- "done"
}(p)
if <- p.Result {
fmt.Println(<-p.Result)
}
// Is it possible to do something else here while wait for 5s?
// Once Promise is fulfilled after 5s, the Result is available.
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做:
Promise主goroutine.异步地在主程序上执行某些操作,同时等待将任何内容发送到其中任何一个Promise.Result或Promise.Error
发送一些内容后,从goroutine返回并使该频道可供阅读.
One*_*One 17
不使用通道的不同方法,使其更快/更高效:
type Promise struct {
wg sync.WaitGroup
res string
err error
}
func NewPromise(f func() (string, error)) *Promise {
p := &Promise{}
p.wg.Add(1)
go func() {
p.res, p.err = f()
p.wg.Done()
}()
return p
}
func (p *Promise) Then(r func(string), e func(error)) {
go func() {
p.wg.Wait()
if p.err != nil {
e(p.err)
return
}
r(p.res)
}()
}
Run Code Online (Sandbox Code Playgroud)
Martin Sulzmann发表了一篇名为“From Events to Futures and Promises and back”的论文(发表于 2016 年 2 月),其中涵盖了该主题。摘要说:
基于通道通信和期货/承诺的事件是强大的,但对于并发编程来说似乎是不同的概念。我们表明,一个概念可以用令人惊讶的很少努力用另一个来表达。我们的结果提供了基于轻量级库的方法来实现事件和期货/承诺。实证结果表明,我们的方法在实践中效果很好。
根据该论文,期货看起来像这样:
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
}
Run Code Online (Sandbox Code Playgroud)
而 promise 的实现方式如下:
type Promise struct {
lock chan int
ft Future
full bool
}
func promise() Promise {
return Promise{make(chan int, 1), make(chan Comp), false}
}
func (pr Promise) future() Future {
return pr.ft
}
Run Code Online (Sandbox Code Playgroud)
阅读论文以了解详细信息、组合器等。