因此,正如这个问题中所解释的,select语句随机选择一个通道操作。我经常看到这样的模式:
func foo(ctx context.Context, someChannel <-chan int) {
for {
select {
case someValue := <-someChannel:
//do some stuff until the context is done
expensiveComputation(someValue)
case <-ctx.Done():
//context is done - either canceled or time is up for timeout
return
}
}
}
但是如果我们不能保证,
case
中的女巫select
会触发,有可能,case <-ctx.Done()
不会立即被选择,但是在expensiveComputation(someValue)
的几次迭代之后,我们实际上不这样做不需要再做,因为上下文已取消。也有可能永远不会被选中,但这概率太低了……
Go 规范还指出 “封闭通道上的接收操作始终可以立即进行,在收到任何先前发送的值后生成元素类型的零值。” 所以也可能的是:
someChannel
现在在 select 语句中将有两个可以继续、可用的操作,并且将随机选择其中之一,并且在取消上下文后可能会执行一些计算。
那么如何正确处理呢?或者,如果我在这里遗漏了一些东西,那是什么?