Создание индикатора ожидания / занятости для выполненного процесса - PullRequest
0 голосов
/ 22 мая 2018

У меня есть программа, которая выполняет дочерний процесс, например

cmd := exec.Command("npm", "install")
log.Printf("Running command and waiting for it to finish...")
err := cmd.Run()
log.Printf("Command finished with error: %v", err)

Во время выполнения этой команды она загружает и устанавливает пакеты npm, которые занимают некоторое время от 10 до 40 секунд, и пользователь не знает, что произойдет, покаон видит стандартный вывод (10-40 секунд зависит от сети), есть кое-что, что я могу использовать, который печатает что-то в cli, чтобы было более ясно, что что-то происходит, какой-то индикатор занятости (любого типа), пока стандартный вывод не будет напечатан вкли?

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Другой способ - перевернуть ответ icza.Поскольку команда npm выполняется долго, вероятно, было бы лучше использовать для нее goroutine вместо тикера (или обоих как goroutine), но это вопрос предпочтений.

Вот так:

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
        }
    }
}
0 голосов
/ 22 мая 2018

Вы можете использовать другую программу для периодической печати чего-либо (например, точки), например, каждую секунду.Когда команда завершится, подайте сигнал о завершении процедуры.

Примерно так:

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

Если вы хотите начинать новую строку после каждых 5 точек, это можно сделать:

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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...