在第一次间隔之前优雅地运行Ticker的身体?

msa*_*ord 2 for-loop timer go

Go的新功能,我已经实现了一个小的Ticker以给定间隔轮询API:

func Poll() <-chan map[uint8]Data {
    json := make(chan map[uint8]Data)

    user, pass, endpoint := credentials.Get()

    ticker := time.NewTicker(90 * time.Second)

    client := &http.Client{}
    req, _ := http.NewRequest("GET", endpoint, nil)
    req.SetBasicAuth(user, pass)

    go func() {
        for range ticker.C {
            resp, _ := client.Do(req)
            bodyText, _ := ioutil.ReadAll(resp.Body)
            json <- extract(string(bodyText))
        }
    }()

    return json
}
Run Code Online (Sandbox Code Playgroud)

显然,在调用第一个轮询的API之前,它会等到第一个整个时间间隔结束; 那是不可取的.

这种天真(但有效)的解决方案似乎...... 很奇怪:

go func() {
    resp, _ := client.Do(req)
    bodyText, _ := ioutil.ReadAll(resp.Body)
    json <- extract(string(bodyText))
}()

go func() {
    for range ticker.C {
        resp, _ := client.Do(req)
        bodyText, _ := ioutil.ReadAll(resp.Body)
        json <- extract(string(bodyText))
    }
}()
Run Code Online (Sandbox Code Playgroud)

是否有更好或更具惯用性的Go方式来实现这一目标?

dav*_*ave 5

我过去这样做过:

for ; true; <-ticker.C {
    resp, _ := client.Do(req)
    bodyText, _ := ioutil.ReadAll(resp.Body)
    json <- extract(string(bodyText))
}
Run Code Online (Sandbox Code Playgroud)

例如:

t := time.NewTicker(2 * time.Second)
now := time.Now()
for ; true; <-t.C {
    fmt.Println(time.Since(now))
}
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/1wz99kzZZ92

  • 您可以进一步将其简化为“for ;;” &lt;-tC {`,我很确定。来自[规范](https://golang.org/ref/spec#For_statements):如果条件不存在,则相当于布尔值true。 (2认同)