2 回答
TA贡献1803条经验 获得超6个赞
http.ListenAndServe(":8080", nil)运行一个无限for循环监听入站连接,这就是为什么如果你之后调用它,代码不会被调用的原因。
然后在这里
ticker := schedule(sendData, time.Second, done)
time.Sleep(60 * time.Second)
close(done)
ticker.Stop()
您将在 60 秒后退出内部循环schedule(),因此您的自动收报机将只运行一次或根本不会运行(取决于完成通道是在自动收报机运行之前还是之后收到值,因为它们是并发的,我们无法确定他们的订单)
所以你想要的是以下内容
func main() {
http.HandleFunc("/data", headers)
ticker := time.NewTicker(time.Minute)
go schedule(ticker)
log.Printf("Ready for data ...%s\n", 8080)
http.ListenAndServe(":8080", nil)
}
func schedule(ticker *time.Ticker) {
for {
// This blocks until a value is received, the ticker
// sends a value to it every one minute (or the interval specified)
<-ticker.C
fmt.Println("Tick")
}
}
您可能已经注意到,一旦服务器连接中断,程序就会终止,因此没有必要使用通道done来退出循环。
TA贡献1900条经验 获得超5个赞
您走在正确的轨道上——您只需要将代码声明包装在一个自执行函数中,然后将其作为 goroutine 运行。ListenAndServe并且Schedule都是阻塞任务,因此它们需要在单独的 go 例程上运行。幸运的是,go 使这很容易实现。
注意 - 此示例代码旨在尽可能接近您的示例。我建议将代码的声明与计划函数分开。
func main() {
http.HandleFunc("/data", func(w http.ResponseWriter, req *http.Request) {}) //line 1
var done chan bool
go func() {
ticker := schedule(func() { fmt.Println("Tick") }, time.Second, done)
time.Sleep(60 * time.Second)
close(done)
ticker.Stop()
}()
fmt.Printf("Ready for data ...%v\n", 8080) //line 2
http.ListenAndServe(":8080", nil) //line 3
}
- 2 回答
- 0 关注
- 72 浏览
添加回答
举报