Skip to content

Instantly share code, notes, and snippets.

@theladyjaye
Last active December 5, 2019 20:58
Show Gist options
  • Save theladyjaye/8d8f3a093c929bf8d800e5827e4dd6ac to your computer and use it in GitHub Desktop.
Save theladyjaye/8d8f3a093c929bf8d800e5827e4dd6ac to your computer and use it in GitHub Desktop.
package async
import (
"sync"
)
type AllResult struct {
values []interface{}
errors []error
hasError bool
}
type AllError struct {
Index int
Error error
}
func (this AllResult) Value(index int) interface{} {
return this.values[index]
}
func (this AllResult) Error(index int) error {
return this.errors[index]
}
func (this AllResult) Errors() []AllError {
var results []AllError
for index, err := range this.errors {
if err != nil {
results = append(results, AllError{Index: index, Error: err})
}
}
return results
}
func (this AllResult) HasError() bool {
return this.hasError
}
func allAction(index int, all *AllResult, action func() (interface{}, error), wg *sync.WaitGroup) {
result, err := action()
all.values[index] = result
all.errors[index] = err
if err != nil {
all.hasError = true
}
wg.Done()
}
func All(actions ...func() (interface{}, error)) <-chan AllResult {
ch := make(chan AllResult)
go func(ch chan AllResult) {
var wg sync.WaitGroup
count := len(actions)
allResult := AllResult{
values: make([]interface{}, count),
errors: make([]error, count),
}
wg.Add(count)
for index, each := range actions {
go allAction(index, &allResult, each, &wg)
}
wg.Wait()
ch <- allResult
close(ch)
}(ch)
return ch
}
package async
import (
"fmt"
"testing"
"time"
)
func TestAll(t *testing.T) {
operations := <-All(
func() (interface{}, error) {
time.Sleep(time.Second * 1)
return true, nil
},
func() (interface{}, error) {
time.Sleep(time.Second * 3)
return "Finished", nil
},
func() (interface{}, error) {
<-time.After(time.Second * 3)
return "Channel Finished", nil
},
)
if operations.HasError() {
fmt.Println("Booo!")
return
}
result1 := operations.Value(0).(bool)
result2 := operations.Value(1).(string)
result3 := operations.Value(2).(string)
fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment