Code can check ctx.Err() during a loop and stop when cancellation appears.

Early Stop

early_stop.go
package main

import (
	"context"
	"fmt"
)

func main() {
	var stopAfter = 
	ctx, cancel := context.WithCancel(context.Background())
	items := []string{"red", "green", "blue", "gold"}

	processed := 0
	for _, item := range items {
		if ctx.Err() != nil {
			break
		}
		processed++
		fmt.Println("item=", item)
		if processed == stopAfter {
			cancel()
		}
	}

	fmt.Println("processed=", processed)
	fmt.Println("err=", ctx.Err())
}
package main

import (
	"context"
	"fmt"
)

func main() {
	var stopAfter = 
	ctx, cancel := context.WithCancel(context.Background())
	items := []string{"red", "green", "blue", "gold"}

	processed := 0
	for _, item := range items {
		if ctx.Err() != nil {
			break
		}
		processed++
		fmt.Println("item=", item)
		if processed == stopAfter {
			cancel()
		}
	}

	fmt.Println("processed=", processed)
	fmt.Println("err=", ctx.Err())
}
package main

import (
	"context"
	"fmt"
)

func main() {
	var stopAfter = 
	ctx, cancel := context.WithCancel(context.Background())
	items := []string{"red", "green", "blue", "gold"}

	processed := 0
	for _, item := range items {
		if ctx.Err() != nil {
			break
		}
		processed++
		fmt.Println("item=", item)
		if processed == stopAfter {
			cancel()
		}
	}

	fmt.Println("processed=", processed)
	fmt.Println("err=", ctx.Err())
}
early stop Cancellation is cooperative: code checks the context and chooses when to stop.