我试图在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.
}

如何执行以下操作:

  1. 运行一个Goroutine,它返回Promise到主要的Goroutine右侧 离开.
  2. 在等待的同时异步地在主 routine 上执行某些操作 任何要寄到Promise.ResultPromise.Error的东西

  3. 一旦有东西被发送,从goroutine返回并完成

推荐答案

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

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)
    }()
}

playground

Go相关问答推荐

JWT库返回及时无效的令牌有效

T的Golang通用切片,其中 *T实现接口

困扰围棋官方巡回赛的S建议所有方法都使用同一类型的接收器

如何在GoFr中为生产和本地环境设置不同的配置?

exec的可执行决议.命令+路径

迭代字符串并用映射值替换原始字符串中的值的惯用方法

我怎样才能改进这个嵌套逻辑以使其正常工作并提高性能

Go Gin:验证 base64

Go struct 匿名字段是公开的还是私有的?

没有任务角色的 AWS CDK ECS 任务定义

assert: mock: I don't know what to return because the method call was unexpected 在 Go 中编写单元测试时出错

如何将一片 map 转换为一片具有不同属性的 struct

如何使用特定的 Go 版本运行 govulncheck?

Go:等待多个通道的性能损失

自定义指标未显示在 prometheus web ui 中,grafana 中也是如此

如何获取多个 url 参数值

无限期运行 Go routine (完成后重新启动)

如何从 Go 1.18 中的单个方法返回两种不同的具体类型?

golang jwt.MapClaims 获取用户ID

从 map 返回空数组而不是空字符串数组