doushao1087 2016-01-28 15:46
浏览 18
已采纳

以不同的持续时间重复倒数

I would like to make a countdown ticker with 2 different durations. What is the best way to do this? I try to do this:

s5 := time.Tick(5 * time.Second)
m5 := time.Tick(5 * time.Minute)

for {
    select {
        case t := <-s5:
            ...
        case t := <-m5:
            ...
    }
}

But I need ticker for different intervals:

5:00 -> 0:00
0:05 -> 0:00
5:00 -> 0:00
0:05 -> 0:00

Which is idiomatic way to do this?

  • 写回答

2条回答 默认 最新

  • dongtong7990 2016-01-28 17:58
    关注

    You could just call sleep if you want

    dur := 1 * time.Second
    nextDur := 3 * time.Second
    
    for {
        time.Sleep(dur)
        dur, nextDur = nextDur, dur
    
        ...
    }
    

    Or alternate the durations in a time.Timer if you need to select. This is what I would personally stick with, since you don't need to worry about the offset between two timers skewing due to scheduling inconsistencies.

    dur := 1 * time.Second
    nextDur := 3 * time.Second
    
    timer := time.NewTimer(dur)
    
    for {
        select {
        case t := <-timer.C:
            dur, nextDur = nextDur, dur
            timer.Reset(dur)
            ...
        }
        ...
    }
    

    Or run 2 timers offset by the smaller interval

    dur1 := 1 * time.Second
    dur2 := 3 * time.Second
    
    timer1 := time.NewTimer(dur1)
    timer2 := time.NewTimer(dur1 + dur2)
    
    for {
        select {
        case t := <-timer1.C:
            timer1.Reset(dur1 + dur2)
            fmt.Println("timer1:", t)
        case t := <-timer2.C:
            timer2.Reset(dur1 + dur2)
            fmt.Println("timer2:", t)
        }
    
    }
    

    And you could also run interleaved Tickers like you originally tried, but that requires a little more coordination to delay the start of one of them

    dur1 := 1 * time.Second
    dur2 := 3 * time.Second
    
    ticker1 := time.NewTicker(dur1)
    ticker2 := time.NewTicker(dur1 + dur2)
    
    var once sync.Once
    delayOnce := func() {
        ticker1.Stop()
        ticker1 = time.NewTicker(dur1 + dur2)
    }
    
    for  {
        select {
        case t := <-ticker1.C:
            once.Do(delayOnce)
            fmt.Println("ticker1:", t)
        case t := <-ticker2.C:
            fmt.Println("ticker2:", t)
        }
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序