Creating waiting/busy indicator for executed process

家住魔仙堡 提交于 2019-12-01 21:47:46

You may use another goroutine to print something (like a dot) periodically, like in every second. When the command completes, signal that goroutine to terminate.

Something like this:

func indicator(shutdownCh <-chan struct{}) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()
    for {
        select {
        case <-ticker.C:
            fmt.Print(".")
        case <-shutdownCh:
            return
        }
    }
}

func main() {
    cmd := exec.Command("npm", "install")
    log.Printf("Running command and waiting for it to finish...")

    // Start indicator:
    shutdownCh := make(chan struct{})
    go indicator(shutdownCh)

    err := cmd.Run()

    close(shutdownCh) // Signal indicator() to terminate

    fmt.Println()
    log.Printf("Command finished with error: %v", err)
}

If you want to start a new line after every 5 dots, this is how it can be done:

func indicator(shutdownCh <-chan struct{}) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()
    for i := 0; ; {
        select {
        case <-ticker.C:
            fmt.Print(".")
            if i++; i%5 == 0 {
                fmt.Println()
            }
        case <-shutdownCh:
            return
        }
    }
}

Another way is to turn icza's answer around. Since the npm command is a long-running execution, it would probably be better to use a goroutine for it instead of the ticker (or both as a goroutine), but it's a matter of preference.

Like this:

func npmInstall(done chan struct{}) {
    cmd := exec.Command("npm", "install")
    log.Printf("Running command and waiting for it to finish...")

    err := cmd.Run()
    if err != nil {
        log.Printf("\nCommand finished with error: %v", err)
    }
    close(done)
}

func main() {
    done := make(chan struct{})
    go npmInstall(done)

    ticker := time.NewTicker(3 * time.Second)
    defer ticker.Stop()
    for {
        select {
        case <-ticker.C:
            fmt.Print(".")
        case <-done:
            fmt.Println()
            return
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!