使用 golang 的 time.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 秒运行第二条记录。但是同样,只有加载到 map 中的第一条记录运行。
最佳答案
您的问题出在这个函数中:
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)
}
}
}
在此部分中,您在 channel time.NewTicker(...).C
上range
:
for range time.NewTicker(v * time.Second).C {
BotSendMsg(conn, channel, k, name)
}
这将尝试从这个 one 代码中读取值,直到 channel C
关闭。这意味着外层循环只进行一次迭代,然后我们阻塞内层循环直到 C
关闭。我们绝不会一次创建多个 Ticker
。
你可以通过在他们自己的 goroutines 中创建代码来解决这个问题:
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)
}
但是您可能希望包含一些同步以确保您可以停止您启动的 goroutines,或者确保可以同时从多个 goroutines 调用 BotSendMsg(...)
时间等
关于go - 使用数据库中的 map 每 x 秒运行一次代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51393608/