使用golang的时间。NewTicker,我试图运行数据库中的每条记录(由文本和计时器组成,即重复之前的秒数),但它仅重复其抓取的第一条记录
func LoadTimedCommands() map[string]time.Duration {
database := InitializeDB()
rows, _ := database.Query("SELECT TimedResponse, Timer from timedcommands")
com := make(map[string]time.Duration)
for rows.Next() {
var TimedResponse string
var Timer time.Duration
rows.Scan(&TimedResponse, &Timer)
com[TimedResponse] = Timer
}
return com
}
func TimedCommands(conn net.Conn, channel string, name string) {
timedcoms := LoadTimedCommands()
for k, v := range timedcoms {
for range time.NewTicker(v * time.Second).C {
BotSendMsg(conn, channel, k, name)
}
}
}
因此,如果我有两个记录要使用: Sqlite data
然后,该代码应每15秒运行一次记录,然后每10秒运行第二条记录。但是,再次,仅运行加载到地图中的第一个记录。
答案 0 :(得分:0)
您的问题出在此功能上
func TimedCommands(conn net.Conn, channel string, name string) {
timedcoms := LoadTimedCommands()
for k, v := range timedcoms {
for range time.NewTicker(v * time.Second).C {
BotSendMsg(conn, channel, k, name)
}
}
}
在本部分中,您range
在time.NewTicker(...).C
频道上的位置:
for range time.NewTicker(v * time.Second).C {
BotSendMsg(conn, channel, k, name)
}
这将尝试从此一个代码行中读取值,直到关闭通道C
。这意味着外部循环仅执行一次迭代,然后我们在内部循环上进行阻塞,直到C
关闭为止。而且我们永远不会一次创建多个Ticker
。
您可以通过在自己的goroutine中创建代码来解决此问题:
for k, v := range timedcoms {
go func(conn net.Conn, channel, name, k string, v time.Duration) {
for range time.NewTicker(v * time.Second).C {
BotSendMsg(conn, channel, k, name)
}
}(conn, channel, k, v)
}
但是您可能需要进行一些同步,以确保可以停止启动的goroutine,或者确保可以同时从多个goroutine中调用BotSendMsg(...)
。