context这个已成为每个框架的标配啦,今天我们看看context常用的几种函数……
1 WithCancel
这个是一个可以取消操作的context,我们看看怎么使用吧
ctx, cancel := context.WithCancel(context.Background())
valCtx := context.WithValue(ctx, key, "withValue")
go watch(valCtx)
time.Sleep(time.Second * 10)
fmt.Println("begin cancel()")
cancel()
fmt.Println("after chancel()")
time.Sleep(5 * time.Second)
fmt.Println("exit all…")
context的取消,会连带子context的结束
2 WithTimeout
我们进行网络请求,执行大型的任务的时候往往会遇到超时,那么怎么认定和知道超时呢?context为我们提供了超时取消的功能
func timeOut(ctx context.Context, outFunc func()) {
loop:
for {
select {
case <-ctx.Done():
fmt.Println("timeout……")
outFunc()
break loop
default:
fmt.Println("time…")
time.Sleep(1 * time.Second)
}
}
}
//调用
withTimeout(time.Second*3, func() {
fmt.Println("over back")
})
上栗程序运行过程中超时之后,select会case到ase <-ctx.Done()。timeout是下文Deadtime的变种
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
return WithDeadline(parent, time.Now().Add(timeout))
}
3 WithDeadline
deadline意为截止日期,给定一个任务的最大期限,当然了,这个任务也可以提前完成。也就是说当执行时间必须≤deadline,可以提前完成,但是不能超越
func withDeadtime(deadtime time.Duration) {
ctx, cancel := context.WithTimeout(context.Background(), deadtime)
defer cancel()
go deadTime(ctx)
time.Sleep(deadtime + time.Second)
}
func deadTime(ctx context.Context) {
loop:
for {
select {
case <-ctx.Done():
fmt.Println("dead…")
break loop
default:
fmt.Println("≥≥≥≥≥")
time.Sleep(time.Second)
}
}
}
当我们在规定时间内完成,则 case <-ctx.Done():是不会被调用的但是系统依然正常结束,而当≥时间采用调用 case <-ctx.Done():
4WithValue
这个就比较有意思啦,让context作为媒介帮忙传递数据
func watch(ctx context.Context) {
loop:
for {
select {
case <-ctx.Done(): //调用cancel之后会执行此处,然后退出
fmt.Println(ctx.Value(key), "exit。。。")
break loop
default:
fmt.Println(ctx.Value(key), "goroute ....")
time.Sleep(1 * time.Second)
}
}
}
好啦,lz也是在刚接触这个context,稍微总结一下,大家可以去读度源码,收获必须杠杠滴