Asynchronous 通过围棋中的渠道实现承诺

Asynchronous 通过围棋中的渠道实现承诺,asynchronous,go,promise,channel,Asynchronous,Go,Promise,Channel,我正在尝试在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{

我正在尝试在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.
}
类型承诺结构{
结果chan字符串
错误信道错误
}
func NewPromise()(*Promise){
r:=制造(成串,1)
e:=制造(chan错误,1)
回报与承诺{
结果:r,
错误:e,
}
}
func main(){
var p=NewPromise()
go func(p*承诺){
时间.睡眠(时间.持续时间(5)*时间.秒)

p、 结果有很多方法可以做到这一点,但我所做的就是调整NewPromise()将函数作为参数,接受结果和错误通道。然后,NewPromise方法使用此函数初始化go例程,返回带有要读取通道的承诺。如果调用.Then方法,这基本上以两个函数作为参数。其中一个函数将处理通过gh结果通道(字符串)和处理错误通道(错误)的结果类型的通道。然后.Then方法调用goroutine中的private.Then()方法以选择首先发生的结果或错误,然后调用适合每个结果的函数

例如,我只使用了一个简单的ticker,它等待一秒钟,然后通过结果通道发送“hi”

我希望这能给你一个这样做的方法

哥朗游乐场:

一种不使用通道的不同方法,使其速度更快/效率更高:

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)
    }()
}
有一篇名为的论文(发表于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
}

阅读本文了解详细信息、combinators和更多信息。

我也在尝试实现javascript的承诺:)。这是一个学习目的项目。在这个实现中,我学习了go's channel、select和goroutine。我认为这个小库满足了您的需要

p := New(func(resolve func(interface{}), reject func(error)) {
    resolve("sonla")
})

p.Then(func(data interface{}) interface{} {
    fmt.Printf("What I get is %v\n", data.(string))
    return nil
})

Await(p)
欢迎您的贡献,如果有人有更好的想法来实现在戈朗的承诺。这是我的

p := New(func(resolve func(interface{}), reject func(error)) {
    resolve("sonla")
})

p.Then(func(data interface{}) interface{} {
    fmt.Printf("What I get is %v\n", data.(string))
    return nil
})

Await(p)