Why does 'tick := time.Tick(time.Second)' ticks every 2 seconds instead of 1 second

Viewed 265

This is rather simple, but I can't figure it out...

I am trying to make a time.Tick every seconds... but it ticks every 2 seconds?!?

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println("Hello, playground")
    
    iterationIndex := 0
    tick := time.Tick(time.Second)
    done := make(chan bool, 1)

    for _ = range tick {
        select {
        case <-tick:
            iterationIndex++
            if iterationIndex >= 10{
                done <- true
            }
            fmt.Printf("%s\n", time.Now().Format("15:04:05.000000"))
        case <-done:
            return
        }
    }
}

links to go playground https://play.golang.org/p/WKhnNK2BRpd

1 Answers

This is where the mistake is:

for _ = range tick {
        select {
        case <-tick:
 

What happens is that you get one tick through for _ = range tick, and another tick through select { case <-tick:. And you log the second tick always.

To log every tick you need to do this:

for {
        select {
        case <-tick:
            iterationIndex++
            if iterationIndex >= 10{
                done <- true
            }
            fmt.Printf("%s\n", time.Now().Format("15:04:05.000000"))
        case <-done:
            return
        }
    }

Here you handle and log each tick.

EDIT:

If you really want to use the for ... range statement instead, you can do something like this:

for _ = range tick{
    if iterationIndex >= 10{
        break
    }
    iterationIndex++
        
    fmt.Printf("%s\n", time.Now().Format("15:04:05.000000"))
}
Related