Skip to content

Commit

Permalink
Add Async2-6 returning tuple inside the channel
Browse files Browse the repository at this point in the history
  • Loading branch information
CorentinClabaut committed Apr 26, 2022
1 parent be2c4dc commit 1373030
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 10 deletions.
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1246,18 +1246,13 @@ Executes a function in a goroutine and returns the result in a channel.
```go
ch := lo.Async(func() error { time.Sleep(10 * time.Second); return nil })
// chan error (nil)

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

### Async{0->1}
### Async{0->6}

Executes a function in a goroutine and returns the result in a channel.
For function without return, the channel will be set once the function finishes.
For function with multiple return values, the results will be returned as a tuple inside the channel.
For function without return, struct{} will be returned in the channel.

```go
ch := lo.Async0(func() { time.Sleep(10 * time.Second) })
Expand All @@ -1268,6 +1263,12 @@ ch := lo.Async1(func() int {
return 42
})
// chan int (42)

ch := lo.Async2(func() (int, string) {
time.Sleep(10 * time.Second);
return 42, "Hello"
})
// chan lo.Tuple2[int, string] ({42, "Hello"})
```

### Must
Expand Down
49 changes: 47 additions & 2 deletions concurrency.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
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)
func Async[A any](f func() A) chan A {
ch := make(chan A)
go func() {
ch <- f()
}()
Expand All @@ -23,3 +23,48 @@ func Async0(f func()) chan struct{} {
func Async1[A any](f func() A) chan A {
return Async(f)
}

// Async2 has the same behavior as Async, but returns the 2 results as a tuple inside the channel.
func Async2[A any, B any](f func() (A, B)) chan Tuple2[A, B] {
ch := make(chan Tuple2[A, B])
go func() {
ch <- T2(f())
}()
return ch
}

// Async3 has the same behavior as Async, but returns the 3 results as a tuple inside the channel.
func Async3[A any, B any, C any](f func() (A, B, C)) chan Tuple3[A, B, C] {
ch := make(chan Tuple3[A, B, C])
go func() {
ch <- T3(f())
}()
return ch
}

// Async4 has the same behavior as Async, but returns the 4 results as a tuple inside the channel.
func Async4[A any, B any, C any, D any](f func() (A, B, C, D)) chan Tuple4[A, B, C, D] {
ch := make(chan Tuple4[A, B, C, D])
go func() {
ch <- T4(f())
}()
return ch
}

// Async5 has the same behavior as Async, but returns the 5 results as a tuple inside the channel.
func Async5[A any, B any, C any, D any, E any](f func() (A, B, C, D, E)) chan Tuple5[A, B, C, D, E] {
ch := make(chan Tuple5[A, B, C, D, E])
go func() {
ch <- T5(f())
}()
return ch
}

// Async6 has the same behavior as Async, but returns the 6 results as a tuple inside the channel.
func Async6[A any, B any, C any, D any, E any, F any](f func() (A, B, C, D, E, F)) chan Tuple6[A, B, C, D, E, F] {
ch := make(chan Tuple6[A, B, C, D, E, F])
go func() {
ch <- T6(f())
}()
return ch
}
90 changes: 90 additions & 0 deletions concurrency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,94 @@ func TestAsyncX(t *testing.T) {
is.Fail("Async1 should not block")
}
}

{
sync := make(chan struct{})

ch := Async2(func() (int, string) {
<-sync
return 10, "Hello"
})

sync <- struct{}{}

select {
case result := <-ch:
is.Equal(result, Tuple2[int, string]{10, "Hello"})
case <-time.After(time.Millisecond):
is.Fail("Async2 should not block")
}
}

{
sync := make(chan struct{})

ch := Async3(func() (int, string, bool) {
<-sync
return 10, "Hello", true
})

sync <- struct{}{}

select {
case result := <-ch:
is.Equal(result, Tuple3[int, string, bool]{10, "Hello", true})
case <-time.After(time.Millisecond):
is.Fail("Async3 should not block")
}
}

{
sync := make(chan struct{})

ch := Async4(func() (int, string, bool, float64) {
<-sync
return 10, "Hello", true, 3.14
})

sync <- struct{}{}

select {
case result := <-ch:
is.Equal(result, Tuple4[int, string, bool, float64]{10, "Hello", true, 3.14})
case <-time.After(time.Millisecond):
is.Fail("Async4 should not block")
}
}

{
sync := make(chan struct{})

ch := Async5(func() (int, string, bool, float64, string) {
<-sync
return 10, "Hello", true, 3.14, "World"
})

sync <- struct{}{}

select {
case result := <-ch:
is.Equal(result, Tuple5[int, string, bool, float64, string]{10, "Hello", true, 3.14, "World"})
case <-time.After(time.Millisecond):
is.Fail("Async5 should not block")
}
}

{
sync := make(chan struct{})

ch := Async6(func() (int, string, bool, float64, string, int) {
<-sync
return 10, "Hello", true, 3.14, "World", 100
})

sync <- struct{}{}

select {
case result := <-ch:
is.Equal(result, Tuple6[int, string, bool, float64, string, int]{10, "Hello", true, 3.14, "World", 100})
case <-time.After(time.Millisecond):
is.Fail("Async6 should not block")
}
}
}

0 comments on commit 1373030

Please sign in to comment.