github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/18channeluse/or_done_channel/main.go (about) 1 package main 2 3 import "fmt" 4 5 /* 6 这种模式是我们经常使用的一种模式, 通过一个信号channel(done)来控制(取消)输入channel的处理。 7 一旦从done channel中读取到一个信号,或者done channel被关闭, 输入channel的处理则被取消。 8 这个模式提供一个简便的方法,把done channel 和 输入 channel 融合成一个输出channel。 9 10 就会context的前身,通过done进行取消整个运行中的任务 11 */ 12 13 func orDone(done <-chan struct{}, c <-chan interface{}) <-chan interface{} { 14 valStream := make(chan interface{}) 15 go func() { 16 defer close(valStream) 17 for { 18 select { 19 case <-done: 20 return 21 case v, ok := <-c: 22 if ok == false { 23 return 24 } 25 select { 26 case valStream <- v: 27 case <-done: 28 } 29 } 30 } 31 }() 32 return valStream 33 } 34 35 func main() { 36 ch := make(chan interface{}) 37 go func() { 38 defer close(ch) 39 40 for i := 0; i < 10; i++ { 41 ch <- i 42 } 43 }() 44 45 for v := range orDone(nil, ch) { 46 fmt.Printf("%v ", v) 47 } 48 }