代码之家  ›  专栏  ›  技术社区  ›  msanford

在第一个间隔前优雅地运行一个断续器的主体?

  •  2
  • msanford  · 技术社区  · 5 年前

    刚开始,我实施了一个 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
    }
    

    显然,在调用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))
        }
    }()
    

    是否有更好或更多的惯用方法来实现这一点?

    1 回复  |  直到 5 年前
        1
  •  5
  •   dave    5 年前

    我以前是这样做的:

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

    例如:

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

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