Skip to content

Commit

Permalink
Merge pull request samber#86 from CorentinClabaut/async
Browse files Browse the repository at this point in the history
Implements Async
  • Loading branch information
samber committed Apr 11, 2022
2 parents 986f172 + 883d71c commit c94a936
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,11 @@ Other functional programming helpers:
- ToSlicePtr
- Empty

Time based helpers:
Concurrency helpers:

- Attempt
- Debounce
- Async

Error handling:

Expand Down Expand Up @@ -1040,7 +1041,6 @@ iter, err := lo.Attempt(0, func(i int) error {

For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).


### Debounce

`NewDebounce` creates a debounced instance that delays invoking functions given until after wait milliseconds have elapsed, until `cancel` is called.
Expand All @@ -1059,6 +1059,21 @@ time.Sleep(1 * time.Second)
cancel()
```

### Async

Executes a function in a goroutine and returns the result in a channel.

```go
ch := lo.Async[error](func() error { time.Sleep(10 * time.Second); return nil })
// chan err{nil}

ch := lo.Async[error](func() Tuple2[int, error] {
time.Sleep(10 * time.Second);
return Tuple2[int, error]{42, nil}
})
// chan Tuple2[int, error]{42, nil}
```

### Must

Wraps a function call to return the given value if the error is nil, panics otherwise.
Expand Down
10 changes: 10 additions & 0 deletions concurrency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package lo

// Async executes a function in a goroutine and returns the result in a channel.
func Async[T any](f func() T) chan T {
ch := make(chan T)
go func() {
ch <- f()
}()
return ch
}
28 changes: 28 additions & 0 deletions concurrency_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package lo

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestAsync(t *testing.T) {
is := assert.New(t)

sync := make(chan struct{})

ch := Async(func() int {
<-sync
return 10
})

sync <- struct{}{}

select {
case result := <-ch:
is.Equal(result, 10)
case <-time.After(time.Millisecond):
is.Fail("Async should not block")
}
}

0 comments on commit c94a936

Please sign in to comment.