Skip to main content
Help improve this documentation

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!

Core - Concurrency helpersโ€‹

This page lists all concurrency operations available in the core package of lo.

  • 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())
  • 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") })
    }
    Prototype:
    func Synchronize(opt ...sync.Locker) *synchronize
  • 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..Async6

    ch := lo.Async(func() int {
    time.Sleep(10 * time.Millisecond)
    return 42
    })
    v := <-ch

    done := lo.Async0(func() {
    time.Sleep(5 * time.Millisecond)
    })
    <-done
    Variant:
    Prototypes:
    func Async[A any](f func() A) <-chan A
    func Async0(f func()) <-chan struct{}
    func Async1[A any](f func() A) <-chan A
    func 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]
  • 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))
  • 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,
    )
    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)
  • 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 += 10
    return a, nil
    },
    func(a Acc) Acc {
    a.Sum -= 10
    return a
    },
    ).
    Then(
    func(a Acc) (Acc, error) {
    a.Sum *= 3
    return a, nil
    },
    func(a Acc) Acc {
    a.Sum /= 3
    return a
    },
    )

    res, err := tx.Process(Acc{Sum: 1})
    // res.Sum == 33, err == nil
    Prototype:
    func NewTransaction[T any]() *Transaction[T]
  • 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())
  • 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())
  • 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())
  • 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())