理解 Context
原文:https://go-rod.github.io/i18n/zh-CN/#/understand-context
收录该文档时间: 2024-11-21T08:12:38+08:00
理解 Context
在此之前,先确保你已经学会了 Goroutines 和 Channels。 Context 主要用于在 Goroutines 之间传递上下文信息,包括:取消信号,超时,截止时间,键值对等等。
例如,我们现在有一个长时间运行的函数 heartbeat
,它每秒会打印一次 beat
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| package main
import (
"fmt"
"time"
)
func main() {
heartbeat()
}
func heartbeat() {
tick := time.Tick(time.Second)
for {
<-tick
fmt.Println("beat")
}
}
|
假如我们想在按下回车键的时候中断 heartbeat,我们可以这样修改代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| func main() {
stop := make(chan struct{})
go func() {
fmt.Scanln()
close(stop)
}()
heartbeat(stop)
}
func heartbeat(stop chan struct{}) {
tick := time.Tick(time.Second)
for {
select {
case <-tick:
case <-stop:
return
}
fmt.Println("beat")
}
}
|
由于这种代码很常见,Golang 把它抽象为了一个 helper 包来处理这种情况,并称之为 Context。 现在用 Context 重新实现上面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| func main() {
ctx, stop := context.WithCancel(context.Background())
go func() {
fmt.Scanln()
stop()
}()
heartbeat(ctx)
}
func heartbeat(ctx context.Context) {
tick := time.Tick(time.Second)
for {
select {
case <-tick:
case <-ctx.Done():
return
}
fmt.Println("beat")
}
}
|