Как запустить функцию после выполнения другой функции в Go с использованием goroutine
Что проверяют
Понимаете ли вы, как в Go передаётся сигнал о завершении между горутинами и зачем вообще нужна горутина в такой задаче. Если вторая функция просто ждёт первую, самый честный ответ: вызвать их последовательно. Следом спрашивают, как передать ошибку из первой функции и как прервать цепочку по таймауту.
Как отвечать
Покажите варианты от простого к сложному:
- последовательно внутри горутины:
go func() { first(); second() }(). Порядок гарантирован, синхронизация не нужна. Подходит, когда вызывающему коду не надо ждать результата; - канал завершения:
done := make(chan struct{}), первая функция делаетclose(done)вdefer, вторая начинается с<-done. Закрытие канала будит всех ожидающих, так удобно запускать несколько зависимых шагов; sync.WaitGroup:wg.Add(1)до запуска горутины,defer wg.Done()внутри,wg.Wait()перед второй функцией. Начиная с Go 1.25 естьwg.Go(f), который делаетAddиDoneсам;errgroup: изgolang.org/x/sync/errgroup,g.Goвозвращает ошибку,g.Wait()отдаёт первую из них, аerrgroup.WithContextотменяет контекст остальным при сбое;context.Context: первая функция проверяетctx.Done(), и цепочку можно прервать таймаутом черезcontext.WithTimeout.
Проговорите, что код, где первая функция запускается в горутине, а следом сразу стоит wg.Wait(), по поведению ничем не отличается от обычного вызова. Горутина имеет смысл, если между запуском и ожиданием выполняется другая работа или первых функций несколько и они идут параллельно.
Где спотыкаются
Вызывают wg.Add(1) внутри самой горутины. Wait может сработать раньше, чем счётчик увеличится, и вторая функция стартует слишком рано. Детектор гонок go test -race может это поймать, но не в каждом прогоне.
Выстраивают порядок через time.Sleep. На нагруженной машине задержки не хватит, и тест начнёт падать случайно.
Передают WaitGroup по значению, а не по указателю. Горутина уменьшает счётчик у копии, и Wait висит вечно. go vet предупреждает о копировании.