0Pricing
Go Academy · Lekcja

WithCancel i WithTimeout

Tworzenie kontekstów możliwych do anulowania i ograniczonych czasowo

WithCancel i WithTimeout to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

context.WithCancel

WithCancel wyprowadza nowy kontekst wraz z funkcją anulowania. Wywołanie cancel zamyka kanał Done wyprowadzonego kontekstu i wszystkich jego kontekstów podrzędnych.

ctx, cancel := context.WithCancel(parent)
defer cancel() // always call to release resources
go doWork(ctx)

Zawsze używaj defer cancel

Nie wywołując cancel, powodujesz wyciek gorutyny monitorującej kontekst nadrzędny. Zawsze używaj defer cancel natychmiast po utworzeniu kontekstu, który można anulować.

context.WithTimeout

WithTimeout wyprowadza kontekst, który automatycznie anuluje się po upływie określonego czasu. Jest to wygodna nakładka na WithDeadline.

ctx, cancel := context.WithTimeout(parent, 5*time.Second)
defer cancel()
if err := db.QueryContext(ctx, query); err != nil {
    // err may be context.DeadlineExceeded
}

Sprawdzanie Err()

Po zamknięciu Done funkcja ctx.Err() zwraca przyczynę: context.Canceled (jawne anulowanie) albo context.DeadlineExceeded (przekroczenie limitu czasu).

if err := ctx.Err(); errors.Is(err, context.DeadlineExceeded) {
    log.Println("timeout")
}

Anulowanie z innej gorutyny

Funkcję cancel można bezpiecznie wywołać z dowolnej gorutyny, a także równocześnie z wielu gorutyn. Skutek ma tylko pierwsze wywołanie.

ctx, cancel := context.WithCancel(context.Background())
go func() {
    if detectError() { cancel() }
}()

Limit czasu żądania HTTP

Ustaw limit czasu dla pojedynczego żądania za pomocą WithTimeout na kontekście odebranego żądania:

func handler(w http.ResponseWriter, r *http.Request) {
    ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
    defer cancel()
    result, err := service.Call(ctx)
    // ...
}

Kaskadowe anulowanie

Jeśli kontekst nadrzędny zostanie anulowany, wszystkie wyprowadzone konteksty (podrzędne i wnuki) zostaną automatycznie anulowane, zatrzymując wszystkie gorutyny w drzewie wywołań.

Context w testach

Używaj context.Background() lub context.WithTimeout w testach, aby ograniczyć czas działania gorutyn uruchamianych przez testy.

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
testResult := runTest(ctx)

Propagowanie context przez biblioteki

Zawsze przekazuj otrzymany context do wywołań wychodzących (zapytań do baz danych, wywołań HTTP i RPC). Nie odrzucaj go ani nie zastępuj, chyba że masz konkretny powód, aby zresetować termin.

Tworzenie context dla zadania w tle

W przypadku zadań w tle, które nie są powiązane z żądaniem, użyj context.Background() jako kontekstu głównego i dodaj WithCancel, aby można było poprawnie zatrzymać zadanie.

select z Done

Zawsze używaj select z ctx.Done() równolegle z kanałem pracy, aby uniknąć blokowania, gdy kontekst zostanie anulowany przed zakończeniem pracy.

select {
case result := <-workCh:
    return result, nil
case <-ctx.Done():
    return nil, ctx.Err()
}

Szybki test

Jaka jest różnica między context.WithCancel a context.WithTimeout?

Podsumowanie: WithCancel i WithTimeout

Najważniejsze informacje:

  • Zawsze używaj defer cancel() natychmiast po utworzeniu kontekstu
  • WithTimeout anuluje kontekst automatycznie po upływie określonego czasu; zwraca DeadlineExceeded
  • ctx.Err() rozróżnia Canceled i DeadlineExceeded
  • Anulowanie jest propagowane do wszystkich wyprowadzonych kontekstów

Często zadawane pytania

Czy lekcja „WithCancel i WithTimeout” jest bezpłatna?

Tak — pełny tekst „WithCancel i WithTimeout” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „WithCancel i WithTimeout”?

Tworzenie kontekstów możliwych do anulowania i ograniczonych czasowo Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „WithCancel i WithTimeout”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dlaczego istnieje context.Context
  2. WithCancel i WithTimeout
  3. WithDeadline i WithValue
  4. Kontekst w wywołaniach HTTP i baz danych
← Powrót do Go Academy