Concurrency - Core helpers
This page lists all concurrency operations available in the core package of lo.
This documentation is still new and evolving. If you spot any mistakes, unclear explanations, or missing details, please open an issue.
Your feedback helps us improve!
NewDebounceโ
Creates a debounced function that delays invoking the callbacks until after the wait duration has elapsed since the last call. Returns the debounced function and a cancel function.
debounce, cancel := lo.NewDebounce(100 * time.Millisecond,func() {println("Called once after debounce!")},)for i := 0; i < 10; i++ {debounce()}time.Sleep(200 * time.Millisecond)cancel()Prototype:func NewDebounce(duration time.Duration, f ...func()) (func(), func())Synchronizeโ
Wraps a callback in a mutex to ensure sequential execution. Optionally accepts a custom locker.
s := lo.Synchronize()for i := 0; i < 10; i++ {go s.Do(func() { println("sequential") })}Similar:Prototype:func Synchronize(opt ...sync.Locker) *synchronizeAsyncXโ
Runs a function asynchronously and returns results via channels. Variants support 0 to 6 return values, using tuple types for multi-value results.
Variants:
Async,Async0..Async6ch := lo.Async(func() int {time.Sleep(10 * time.Millisecond)return 42})v := <-chdone := lo.Async0(func() {time.Sleep(5 * time.Millisecond)})<-doneVariant:Prototypes:func Async[A any](f func() A) <-chan Afunc Async0(f func()) <-chan struct{}func Async1[A any](f func() A) <-chan Afunc Async2[A, B any](f func() (A, B)) <-chan Tuple2[A, B]func Async3[A, B, C any](f func() (A, B, C)) <-chan Tuple3[A, B, C]func Async4[A, B, C, D any](f func() (A, B, C, D)) <-chan Tuple4[A, B, C, D]func Async5[A, B, C, D, E any](f func() (A, B, C, D, E)) <-chan Tuple5[A, B, C, D, E]func Async6[A, B, C, D, E, F any](f func() (A, B, C, D, E, F)) <-chan Tuple6[A, B, C, D, E, F]NewDebounceByโ
Creates a debounced function per key that delays invoking callbacks until after the wait duration has elapsed for that key. Returns a per-key debounced function and a per-key cancel function.
debounce, cancel := lo.NewDebounceBy[string](100*time.Millisecond,func(key string, count int) {println(key, count)},)for i := 0; i < 10; i++ {debounce("first")}time.Sleep(200 * time.Millisecond)cancel("first")Prototype:func NewDebounceBy[T comparable](duration time.Duration, f ...func(key T, count int)) (func(key T), func(key T))WaitForโ
Runs periodically until a condition is validated. Use WaitFor for simple predicates, or WaitForWithContext when you need context cancellation/timeout inside the predicate. Both return total iterations, elapsed time, and whether the condition became true.
iterations, elapsed, ok := lo.WaitFor(func(i int) bool {return i > 5},10*time.Millisecond,time.Millisecond,)With context:
iterations, elapsed, ok := lo.WaitForWithContext(context.Background(),func(_ context.Context, i int) bool {return i >= 5},10*time.Millisecond,time.Millisecond,)Variant:Prototypes:func WaitFor(condition func(i int) bool, timeout time.Duration, heartbeatDelay time.Duration) (totalIterations int, elapsed time.Duration, conditionFound bool)func WaitForWithContext(ctx context.Context, condition func(ctx context.Context, i int) bool, timeout time.Duration, heartbeatDelay time.Duration) (totalIterations int, elapsed time.Duration, conditionFound bool)NewTransactionโ
Creates a new Saga transaction that chains steps with rollback functions.
Use Then to add steps with exec and rollback functions. Call Process with an initial state to execute the pipeline; if a step returns an error, previously executed steps are rolled back in reverse order using their rollback functions.
type Acc struct{ Sum int }tx := lo.NewTransaction[Acc]().Then(func(a Acc) (Acc, error) {a.Sum += 10return a, nil},func(a Acc) Acc {a.Sum -= 10return a},).Then(func(a Acc) (Acc, error) {a.Sum *= 3return a, nil},func(a Acc) Acc {a.Sum /= 3return a},)res, err := tx.Process(Acc{Sum: 1})// res.Sum == 33, err == nilSimilar:Prototype:func NewTransaction[T any]() *Transaction[T]NewThrottleโ
Creates a throttled function that invokes callbacks at most once per interval. Returns the throttled function and a reset function.
throttle, reset := lo.NewThrottle(100*time.Millisecond,func() {println("tick")},)for i := 0; i < 10; i++ {throttle();time.Sleep(30*time.Millisecond)}reset()Prototype:func NewThrottle(interval time.Duration, f ...func()) (throttle func(), reset func())NewThrottleWithCountโ
Creates a throttled function with a per-interval invocation limit.
throttle, reset := lo.NewThrottleWithCount(100*time.Millisecond,3,func() {println("tick")},)for i := 0; i < 10; i++ {throttle();time.Sleep(30*time.Millisecond)}reset()Prototype:func NewThrottleWithCount(interval time.Duration, count int, f ...func()) (throttle func(), reset func())NewThrottleByโ
Creates a throttled function per key.
throttle, reset := lo.NewThrottleBy[string](100*time.Millisecond,func(key string) {println(key)},)for i := 0; i < 10; i++ {throttle("foo");time.Sleep(30*time.Millisecond)}reset()Prototype:func NewThrottleBy[T comparable](interval time.Duration, f ...func(key T)) (throttle func(key T), reset func())NewThrottleByWithCountโ
Creates a throttled function per key with a per-interval invocation limit.
throttle, reset := lo.NewThrottleByWithCount[string](100*time.Millisecond,3,func(key string) {println(key)},)for i := 0; i < 10; i++ {throttle("foo")}reset()Prototype:func NewThrottleByWithCount[T comparable](interval time.Duration, count int, f ...func(key T)) (throttle func(key T), reset func())