由于我不是一个有经验的围棋开发者,我不明白如何使用Ticker。我有以下的场景:
一个运行在特定端口8080上的go web服务,它从另一个应用程序获取数据并处理数据。到目前为止一切都很好,但我在这个web服务中有另一个sendData
函数,它循环通过一些文件并将它们发送到另一个外部服务。我尝试每隔1分钟调用一次sendData()
函数。下面是主函数在没有标记的情况下的外观:
func main() {
http.HandleFunc("/data", headers) //line 1
log.Printf("Ready for data ...%s\n", 8080) //line 2
http.ListenAndServe(":8080", nil) //line 3
}
如果我在line 2
之后添加Ticker,它将保持无限循环。如果我在line 3
之后添加Ticker,程序将不会调用Ticker。您知道如何处理这个问题吗?
股票代码部分
ticker := schedule(sendData, time.Second, done)
time.Sleep(60 * time.Second)
close(done)
ticker.Stop()
和schedule from之间的关系
func schedule(f func(), interval time.Duration, done <-chan bool) *time.Ticker {
ticker := time.NewTicker(interval)
go func() {
for {
select {
case <-ticker.C:
f()
case <-done:
return
}
}
}()
return ticker
因此,基本上我想发送数据evert分钟或小时等。有人能解释内部Ticker如何工作吗?
2条答案
按热度按时间qjp7pelc1#
http.ListenAndServe(":8080", nil)
运行一个无限的for
循环来侦听入站连接,这就是为什么如果您以后调用它,不会调用ticker。然后这里
60秒后退出
schedule()
内部的循环,因此您的ticker将只运行一次或根本不运行(取决于done通道是在ticker滴答之前还是之后接收到值,因为它们是并发的,我们无法确定它们的顺序)所以你需要的是
正如您可能已经注意到的,一旦服务器连接中断,程序将终止,因此没有必要使用
done
通道退出循环。Try it here
jaxagkaj2#
你的思路是正确的--你只需要把代码声明封装在一个自执行函数中,然后把它作为goroutine运行。
ListenAndServe
和Schedule
都是阻塞任务,所以它们需要在单独的go例程上运行,幸运的是go使这一点变得非常简单。