Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何获得时间。立即打勾_Go_Timer - Fatal编程技术网

Go 如何获得时间。立即打勾

Go 如何获得时间。立即打勾,go,timer,Go,Timer,我有一个循环,它会迭代直到作业启动并运行: 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 Int

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

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")
    }
}

在生产中效果很好。唯一的问题是它使我的测试变慢了。他们都至少要等2秒钟才能完成。还有时间吗?滴答滴答地立即滴答?

滴答器在内部的实际实现相当复杂。但你可以用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
}

如果要立即检查作业,请不要在for循环中使用ticker作为条件。例如:

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")
    }
}
如果您仍然需要检查DoesNoteSisterRor,那么您需要确保在自动售票机之后进行检查,这样您就不会有繁忙的等待

ticker := time.NewTicker(period)
for ; true; <-ticker.C {
    ...
}
不幸的是,it Go开发人员在任何可预见的未来都不会添加此类功能,因此我们必须应对

有两种常用的方法使用ticker:

for循环 考虑到这样的情况:

股票代码:=time.NewTickerperiod 暂停
因为我做了这样的东西

func main() {
    t := time.Now()
    callme := func() {
        // do somethign more
        fmt.Println("callme", time.Since(t))
    }
    ticker := time.NewTicker(10 * time.Second)
    first := make(chan bool, 1)
    first <- true
    for {
        select {
        case <-ticker.C:
            callme()
        case <-first:
            callme()
        }
        t = time.Now()
    }
    close(first)
}

我认为这对于for select循环来说可能是一个有趣的选择,特别是如果案例的内容不是一个简单的函数:

具有:

中断:=makechan操作系统信号,1 信号中断,操作系统中断 股票代码:=time.NewTickerperiod 暂停 循环: 为了{ 挑选{
case-Whoops,谢谢你的提醒。在测试中将ticker和其他持续时间设置为较小的值。这些作业实际上是在远程服务上运行的。虽然可以让该程序在本地运行服务器并修改远程服务以接受订阅,但该解决方案在我看来过于繁重了。@JimB抱歉我的无知,但是什么呢这是您所指的围绕作业的竞争条件。状态?是假定作业是共享对象吗?@Xavi:将您的代码封装在函数中,使用变量作为计时器延迟和超时值,在测试时将这些变量设置为较小的值。您不能立即发送到计时器通道吗?这是一个仅接收的通道:键入Ticker struct{C这是正确的解决方案imo-也出现在stdlib中,请参阅只是为了增加它。如果你不想失去从chan获得的价值,你可以为t:=时间。现在;真的;t=Does@youfu你完全正确!我刚刚编辑了我的答案。