import "github.com/Fliko/cardinal"
Package cardinal is a Promise library written in Go using the reflect package.
Before getting started there a few basic rules you need to understand:
1. To reject a promise return a non-nil error 2. Nil errors will not be piped into the next chained function
cardinal.go cardinal_functions.go
type PromiseStruct struct {
Status stat // Describes the success of the previously ran promise
Result []reflect.Value // Holds the function output arguments of the previously ran promise
Order int // For promise methods that return multiple promises, this is used to keep their return arguments in order
}PromiseStruct holds the data for running the Promise
should type check and throw a sensible error
Code:
stuff := Promise(func() int {
return 3
}).
Then(func(x int) (int, error) {
fmt.Println(x)
return x * x, nil
}).
Then(func(x float64) (float64, error) {
fmt.Println(x)
return x * x, nil
}).
Catch(func(e error) error {
fmt.Println(e)
return e
})
fmt.Println(stuff.Result[0])
Output:
3 Args should be float64 but got int Args should be float64 but got int
func Promise(fn interface{}) PromiseStructPromise is a generator for the PromiseStruct and it only accepts functions with no input arguments
should be able to chain then functions piping the values from one to the other
Code:
stuff := Promise(func() int {
return 3
}).
Then(func(x int) int {
fmt.Println(x)
return x * x
}).
Then(func(x int) {
fmt.Println(x)
})
fmt.Println(stuff.Result)
Output:
3 9 []
func (p PromiseStruct) All(fn ...interface{}) PromiseStruct
All takes several functions and runs them in parallel The next chaining function will need to take the input of all function returns in order
should type check and throw a sensible error
Code:
stuff := Promise(func() int {
return 3
}).
All(
func(x int) (int, error) {
fmt.Println(x)
time.Sleep(50 * time.Millisecond) //Guarantee Order
return x + 3, nil
},
func(x int) (int, error) {
fmt.Println(x)
return x * x, nil
})
fmt.Println(stuff.Result[0])
fmt.Println(stuff.Result[1])
Output:
3 3 6 9
should properly pass the result of All to a Then
Code:
stuff := Promise(func() int {
return 3
}).
All(
func(x int) (int, error) {
fmt.Println(x)
return x * x, nil
},
func(x int) (int, error) {
fmt.Println(x)
return x * x, nil
}).
Then(func(x int, y int) int {
fmt.Println(x, y)
return x * y
})
fmt.Println(stuff.Result[0])
Output:
3 3 9 9 81
func (p PromiseStruct) Catch(fn interface{}) PromiseStruct
Catch runs a given function if any promise before it failed to complete successfully
should skip Then and run Catch if error returned is not nil
Code:
stuff := Promise(func() int {
return 3
}).
Then(func(x int) (int, error) {
fmt.Println(x)
return x * x, errors.New("should show up in Catch")
}).
Then(func(x int) (int, error) {
fmt.Println(x)
return x * x, nil
}).
Catch(func(e error) error {
fmt.Println(e)
return e
})
fmt.Println(stuff.Result[0])
Output:
3 should show up in Catch should show up in Catch
func (p PromiseStruct) Map(s interface{}, fn interface{}) PromiseStruct
Map takes an array and applies a given function to each element in the array The return of Map is similar to All, the next chained method will need to handle all passed returns in order
Should map a given array with a given function
Code:
fruits := []string{"apples", "bananas", "oranges", "cherries"}
stuff := Promise(func() {}).
Map(fruits, func(s string) string {
return s + " are not a fruit"
}).
Then(func(a string, b string, c string, d string) string {
fmt.Println(a)
return b + " and " + d
})
fmt.Println(stuff.Result[0])
Output:
apples are not a fruit bananas are not a fruit and cherries are not a fruit
func (p PromiseStruct) Reduce(s interface{}, fn interface{}, init interface{}) PromiseStruct
Reduce takes a slice and give a function and initial value creates a single value
should reduce a given array with a given function
Code:
fruits := []string{"apples", "bananas", "oranges", "cherries"}
stuff := Promise(func() {}).
Reduce(fruits, func(a string, b string, i int, l int) string {
return a + " " + b
}, nil).
Then(func(s string) string {
fmt.Println(s)
return s
})
fmt.Println(stuff.Result[0])
Output:
apples bananas oranges cherries apples bananas oranges cherries
func (p PromiseStruct) Then(fn interface{}) PromiseStruct
Then runs a given function with the piped in parameters as long as the previous promise was successful
should not skip Then and not run Catch if error returned is nil
Code:
stuff := Promise(func() int {
return 3
}).
Then(func(x int) (int, error) {
fmt.Println(x)
return x * x, nil
}).
Then(func(x int) (int, error) {
fmt.Println(x)
return x * x, nil
})
fmt.Println(stuff.Result[0])
Output:
3 9 81
func (p PromiseStruct) ThenMap(fn interface{}) PromiseStruct
ThenMap is like Map but takes the array from the previously executed promise
should map a piped array with a given function
Code:
fruits := []string{"apples", "bananas", "oranges", "cherries"}
stuff := Promise(func() []string { return fruits }).
Map(fruits, func(s string) string {
return s + " are not a fruit"
}).
Then(func(a string, b string, c string, d string) string {
fmt.Println(a)
return b + " and " + d
})
fmt.Println(stuff.Result[0])
Output:
apples are not a fruit bananas are not a fruit and cherries are not a fruit
func (p PromiseStruct) ThenReduce(fn interface{}, init interface{}) PromiseStruct
ThenReduce is like Reduce but the slice comes from a previous promise
Code:
fruits := []string{"apples", "bananas", "oranges", "cherries"}
stuff := Promise(func() []string { return fruits }).
ThenReduce(func(a string, b string, i int, l int) string {
return a + " " + b
}, "grapes")
fmt.Println(stuff.Result[0])
Output:
grapes apples bananas oranges cherries
Package cardinal imports 2 packages (graph). Updated 2018-10-24. Refresh now. Tools for package owners.