如何获得时间.请立即勾选

Xav*_*avi 6 timer go

我有一个迭代循环,直到作业启动并运行:

ticker := time.NewTicker(time.Second * 2)
defer ticker.Stop()

started := time.Now()
for now := range ticker.C {
    job, err := client.Job(jobID)
    switch err.(type) {
    case DoesNotExistError:
        continue
    case InternalError:
        return err
    }

    if job.State == "running" {
        break
    }

    if now.Sub(started) > time.Minute*2 {
        return fmt.Errorf("timed out waiting for job")
    }
}
Run Code Online (Sandbox Code Playgroud)

在生产中很有效.唯一的问题是它使我的测试变慢.他们都在完成前至少等待2秒钟.无论如何要time.Tick立即打勾?

w11*_*00n 7

ticker := time.NewTicker(period)
for ; true; <-ticker.C {
    ...
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/golang/go/issues/17601

  • 只是为了补充这一点。如果您不想失去从 chan 获得的价值,您可以执行 `for t := time.Now(); 真的; t = &lt;-ticker.C {` (4认同)

Cal*_*leb 5

Ticker内部的实际实现是相当复杂的。但是你可以用一个 goroutine 包装它:

func NewTicker(delay, repeat time.Duration) *time.Ticker {
    ticker := time.NewTicker(repeat)
    oc := ticker.C
    nc := make(chan time.Time, 1)
    go func() {
        nc <- time.Now()
        for tm := range oc {
            nc <- tm
        }
    }()
    ticker.C = nc
    return ticker
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个仅接收通道:`type Ticker struct { C &lt;-chan Time // 传递报价的通道。// 包含过滤或未导出的字段 }` (2认同)

Jim*_*imB 5

如果您想立即检查作业,请不要使用自动收报机作为 for 循环中的条件。例如:

ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()

started := time.Now()
for {
    job, err := client.Job(jobID)
    if err == InternalError {
        return err
    }

    if job.State == "running" {
        break
    }

    now := <-ticker.C
    if now.Sub(started) > 2*time.Minute {
        return fmt.Errorf("timed out waiting for job")
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您仍然需要检查DoesNotExistError,则要确保在自动收报机之后进行检查,以免忙于等待。


Bor*_*per 5

不幸的是,Go开发人员似乎不会在任何可预见的将来添加此类功能,因此我们必须应对...

有两种使用股票行情的常用方法:

for

给定这样的东西:

for <- time.Tick(period) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用:


for ; true; <- time.Tick(period) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

for- select循环

给定这样的东西:

interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)

loop:
for {
    select {
        case <- time.Tick(period): 
            f()
        case <- interrupt:
            break loop
    }
}
Run Code Online (Sandbox Code Playgroud)

使用:

interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)

loop:
for {
    f()

    select {
        case <- time.Tick(period): 
            continue
        case <- interrupt:
            break loop
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `&lt;- time.Tick(period)` 是否在每次迭代时创建一个 Ticker ?根据文档,Tick 创建的 Ticker 不能被垃圾回收。这让我害怕。 (3认同)