为了账号安全,请及时绑定邮箱和手机立即绑定

选择阻塞的呼叫和频道

选择阻塞的呼叫和频道

Go
素胚勾勒不出你 2022-06-27 16:12:15
我很确定我以前看过一个关于此的问题,但现在找不到。本质上,我想select在一个被阻止的呼叫以及一个频道上。我知道我可以将阻塞的调用推送到 goroutine 中并通过通道等待结果,但这感觉像是错误的解决方案。有没有一种惯用的方式来写我缺少的这个?最理想的情况是:select {case a <- c:  ...case ans := connection.Read():  ...}
查看完整描述

1 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

如果你有一个你想要的通道和函数select,使用 goroutine 和通道是惯用的解决方案。请注意,如果从通道接收到值,则不会影响函数,它将继续运行。您可以使用context.Context它来表示不再需要它的结果,并且它可能会提前终止。


如果您被允许重构,您可以“使”函数在同一通道上发送,因此您只需要从单个通道接收。


另一个重构想法是让函数监视相同的通道并提前返回,所以你可以只做一个没有select.


请注意,如果您需要在许多地方执行此操作,您可以创建一个辅助函数来异步启动它:


func launch(f func()) <-chan struct{} {

    done := make(chan struct{})

    go func() {

        defer close(done)

        f()

    }()

    return done

}

示例函数:


func test() {

    time.Sleep(time.Second)

}

然后使用它:


select {

case a := <-c:

    fmt.Println("received from channel:", a)

case <-launch(test):

    fmt.Println("test() finished")


}


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信