package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
start := time.Now()
results := Google("golang")
fmt.Println(results)
fmt.Printf("%s", time.Since(start))
}
type Result string
type Search func(key string) Result
func ResourceSearch(kind string) Search {
return func(key string) Result {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
return Result(fmt.Sprintf("<%s from %s server>\n", key, kind))
}
}
func FirstSearch(servers []Search, key string) Result {
result := make(chan Result)
done := make(chan struct{})
defer close(done)
first := func(i int) {
select {
case <-done:
return
case result <- servers[i](key):
}
}
for i := range servers {
go first(i)
}
return <-result
}
func Google(key string) (results []Result) {
var images []Search
var videos []Search
var voices []Search
for i := 0; i < 3; i++ {
images = append(images, ResourceSearch(fmt.Sprintf("image-%d", i)))
videos = append(videos, ResourceSearch(fmt.Sprintf("video-%d", i)))
voices = append(voices, ResourceSearch(fmt.Sprintf("voice-%d", i)))
}
chanResults := make(chan Result)
go func() {
chanResults <- FirstSearch(images, key)
}()
go func() {
chanResults <- FirstSearch(videos, key)
}()
go func() {
chanResults <- FirstSearch(voices, key)
}()
after := time.After(80 * time.Millisecond)
for i := 0; i < 3; i++ {
select {
case r := <-chanResults:
results = append(results, r)
case <-after:
fmt.Println("timeout")
return
}
}
return
}
有疑问加站长微信联系(非本文作者)