介绍
for-select-channel
的使用
1. 定义
先理解三个概念:
没有条件的
for
是死循环:
for {
//code here
}
select-case
是专门用来轮询通道channel是否有值传递过来,有多个的时候会随机选择一个
符合条件的case
,如果一个也没有且没有default
选项,它将成为一个阻塞操作,
直到有新的值符合case
为止, 有点像前面讲到的 [WaitGroup
(https://blog.csdn.net/wujiangwei567/article/details/86683993)
select {
case <-channelA :
case b := <-channelB :
//oper b
}
通道
channel <- 10 //发送数据10
num := <- channel // 接收数据
2. 使用实例
我们使用goroutine 执行多个任务,比如列表和数量的同时查询,我们不知道
谁先谁后返回,什么时候返回,什么时候完成,那么我们就可以使用for-select
来实现数据的接收
package main
import (
"fmt"
"time"
)
func getTotal(total chan interface{}) {
//假设数据库 查询了一番发现是 12条记录
time.Sleep(3*time.Second)
total <- 12
}
func getList(data chan interface{}){
//假设这里做了一系列查询操作 返回一系列数据
list := struct {
name string
age int
}{
"zhangsan",
18,
}
time.Sleep(2*time.Second)
data <- list
}
func main() {
var total int
var data interface{}
done := make(chan interface{})
defer close(done)
go getTotal(done) //获取 总数
go getList(done) //获取列表
for {
if total > 0 && data != nil {
break
}
select {
case result := <-done :
switch result.(type) {
case int :
total = result.(int)
default:
data = result
}
case <-time.After(4 * time.Second) :
fmt.Println("time out exit ")
return
}
}
fmt.Println("total is ",total)
fmt.Println("data is ",data)
}
打印结果:
total is 12
data is {zhangsan 18}
这里用到了 定时器通道
time.After
的使用,如果所有通道到达超时时间后,仍然没有返回或退出,定时器会自动给该通道发送数据,使得select
选择这一case