如何解决选择阻止的呼叫和频道
我很确定我之前已经看过一个问题,但是现在找不到。
本质上,我想select
通话和频道都被阻止。
我知道我可以将阻止的调用放入goroutine并通过通道等待结果,但是这感觉像是错误的解决方案。
是否有一种惯用的方式来写我所缺少的东西?
最理想的情况是:
select {
case a <- c:
...
case ans := connection.Read():
...
}
解决方法
如果您有一个频道和想要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")
}
在Go Playground上尝试。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。