Select

This allows you to wait on multiple channels

func fib(c, quit chan int) {
	x := 0
	y := 1

	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			close(c)
			return
		default:
			// this only runs if no other case is run
		}
	}
}

func main() {
	c := make(chan int, 10)
	quit := make(chan int)

	go func() {
		for i := 0; i < 10; i++ {
			fmt.Printf("%v,", <-c)
		}
		quit <- 1
		close(quit)
	}()

	fib(c, quit)
}

Examples

Ping

Consider that select blocks until one channel returns a value

func Racer(a, b string) string {
	select {
	case <-ping(a):
		return a
	case <-ping(b):
		return b
	}
}

func ping(url string) chan struct{} {
	ch := make(chan struct{})
	go func() {
		resp, _ := http.Get(url)
		_ = resp.Body.Close()
		close(ch)
	}()
	return ch
}