Skip to content
File

Blob: util/promise/promise.go

go41 lines
1package promise
2 
3import (
4 "context"
5 "sync"
6)
7 
8// All provides similar concurrency to JavaScript's Promise.All, however with 1 distinction. []func that
9// are passed in must respect fnCtx cancellation and returns, otherwise All will block even if fnCtx is cancelled.
10func All[V comparable](fnCtx context.Context, fns ...func(fnCtx context.Context) (V, error)) ([]V, []error) {
11 var (
12 wg = sync.WaitGroup{}
13 results = make([]V, len(fns))
14 errors = make([]error, len(fns))
15 done = make(chan struct{}, 1)
16 )
17 wg.Add(len(fns))
18 go func() {
19 wg.Wait()
20 close(done)
21 }()
22 for i, fn := range fns {
23 go func(i int, fn func(context.Context) (V, error)) {
24 defer wg.Done()
25 v, e := fn(fnCtx)
26 if e != nil {
27 errors[i] = e
28 return
29 }
30 results[i] = v
31 }(i, fn)
32 }
33 select {
34 case <-done:
35 case <-fnCtx.Done():
36 // assert that the fn returns first
37 <-done
38 }
39 return results, errors
40}