我有一个迭代循环,直到作业启动并运行:
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秒钟。有没有让time.Tick
立刻打勾?
答案 0 :(得分:6)
ticker := time.NewTicker(period)
for ; true; <-ticker.C {
...
}
答案 1 :(得分:2)
内部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
}
答案 2 :(得分:2)
如果您想立即检查作业,请不要使用代码作为for循环中的条件。例如:
ticker := time.NewTicker(time.Second * 2)
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")
}
}
如果你仍然需要检查DoesNotExistError
,你需要确保在代码之后这样做,这样你就没有忙碌等待。
答案 3 :(得分:1)
不幸的是,seems Go开发人员不会在任何可预见的将来添加此类功能,因此我们必须应对...
有两种使用股票行情的常用方法:
for
循环给出类似这样的内容:
for <- time.Tick(period) {
...
}
使用:
for ; true; <- time.Tick(period) {
...
}
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
}
}
使用:
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
loop:
for {
f()
select {
case <- time.Tick(period):
continue
case <- interrupt:
break loop
}
}
答案 4 :(得分:1)
我煮了这样的东西
{{1}}
答案 5 :(得分:0)
我认为这可能是for-select
循环的一个有趣的替代方法,特别是在case
的内容不是简单函数的情况下:
具有:
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
ticker := time.NewTicker(period)
defer ticker.Stop()
loop:
for {
select {
case <- ticker.C:
f()
case <- interrupt:
break loop
}
}
使用:
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
ticker := time.NewTicker(period)
defer ticker.Stop()
firstTick := false
// create a wrapper of the ticker that ticks the first time immediately
tickerChan := func() <-chan time.Time {
if !firstTick {
firstTick = true
c := make(chan time.Time, 1)
c <- time.Now()
return c
}
return ticker.C
}
loop:
for {
select {
case <- tickerChan():
f()
case <- interrupt:
break loop
}
}