猿问

在 Go 中以一定间隔同时运行多个函数

我有一个函数列表和它们各自的间隔。我想同时运行每个函数的时间间隔。

在 JavaScript 中,我写了类似这样的东西:

maps.forEach(({fn, interval}) => {
    setInterval(fn, interval)
})

我如何在 Golang 中实现此功能?


呼如林
浏览 97回答 1
1回答

波斯汪

使用 atime.Ticker定期接收“事件”,您可以使用它来为函数的执行计时。time.Ticker您可以通过致电获得time.NewTicker()。返回的代码有一个定期发送值的通道。使用 goroutine 连续接收事件并调用函数,例如使用循环for range。让我们看看 2 个函数:func oneSec() {    log.Println("oneSec")}func twoSec() {    log.Println("twoSec")}这是一个定期调用给定函数的简单调度程序:func schedule(f func(), interval time.Duration) *time.Ticker {    ticker := time.NewTicker(interval)    go func() {        for range ticker.C {            f()        }    }()    return ticker}使用它的例子:func main() {    t1 := schedule(oneSec, time.Second)    t2 := schedule(twoSec, 2*time.Second)    time.Sleep(5 * time.Second)    t1.Stop()    t2.Stop()}示例输出(在Go Playground上尝试):2009/11/10 23:00:01 oneSec2009/11/10 23:00:02 twoSec2009/11/10 23:00:02 oneSec2009/11/10 23:00:03 oneSec2009/11/10 23:00:04 twoSec2009/11/10 23:00:04 oneSec请注意,Ticker.Stop()不会关闭代码通道,因此 afor range不会终止;Stop()仅停止在代码通道上发送值。如果您想终止用于安排函数调用的 goroutine,您可以使用额外的通道来完成。然后那些 goroutines 可能会使用一个select语句来“监控”ticker 的频道和这个done频道,如果从中接收done成功则返回。例如: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}并使用它:func main() {    done := make(chan bool)    t1 := schedule(oneSec, time.Second, done)    t2 := schedule(twoSec, 2*time.Second, done)    time.Sleep(5 * time.Second)    close(done)    t1.Stop()    t2.Stop()}请注意,即使在这个简单的示例中没有必要停止代码(因为当maingoroutine 结束时,程序也会结束),在现实生活中,如果应用程序继续运行,让代码不停止会浪费资源(它们会继续使用后台 goroutine,并将继续尝试在他们的频道上发送值)。最后的话:如果您有一段函数区间对,只需使用循环将每一对传递给此schedule()函数即可。是这样的:type pair struct {    f        func()    interval time.Duration}pairs := []pair{    {oneSec, time.Second},    {twoSec, 2 * time.Second},}done := make(chan bool)ts := make([]*time.Ticker, len(pairs))for i, p := range pairs {    ts[i] = schedule(p.f, p.interval, done)}time.Sleep(5 * time.Second)close(done)for _, t := range ts {    t.Stop()}
随时随地看视频慕课网APP

相关分类

Go
我要回答