A type-safe Promise-like asynchronous programming library for Go, providing chainable operations with error handling and timeout control.
- Type Safe: Uses Go generics for compile-time type checking
- Chainable: Supports
Then(),Catch(),Finally()method chaining - Timeout Control: Built-in context timeout support
- Concurrent Operations:
FeatureAllandFeatureRacemethods - Lightweight: Goroutine-based implementation
go get github.com/muzig/go-featurepackage main
import (
"fmt"
"go-feature/feature"
"time"
)
func main() {
// Create an async operation
f := feature.NewFeature(func(resolve func(string), reject func(error)) {
time.Sleep(1 * time.Second)
resolve("Hello from Feature!")
})
// Wait for result
result, err := f.Await()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Result: %s\n", result)
}f := feature.NewFeature(func(resolve func(int), reject func(error)) {
time.Sleep(500 * time.Millisecond)
resolve(10)
})
result, err := f.Then(func(x int) int {
return x * 2
}).Then(func(x int) int {
return x + 5
}).Catch(func(err error) int {
fmt.Printf("Caught error: %v\n", err)
return 0
}).Finally(func() {
fmt.Println("Operation completed")
}).Await()f := feature.NewFeature(func(resolve func(string), reject func(error)) {
reject(fmt.Errorf("something went wrong"))
})
result, err := f.Catch(func(err error) string {
fmt.Printf("Caught error: %v\n", err)
return "fallback value"
}).Await()// Wait for all operations to complete
features := []*feature.Feature[int]{
feature.NewFeature(func(resolve func(int), reject func(error)) {
time.Sleep(200 * time.Millisecond)
resolve(1)
}),
feature.NewFeature(func(resolve func(int), reject func(error)) {
time.Sleep(300 * time.Millisecond)
resolve(2)
}),
}
allResults, err := feature.FeatureAll(features...).Await()
// Race operation - return first completed result
raceResult, err := feature.FeatureRace(features...).Await()ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
slowFeature := feature.NewFeature(func(resolve func(string), reject func(error)) {
time.Sleep(2 * time.Second)
resolve("This will timeout")
})
_, err := slowFeature.AwaitWithContext(ctx)
if err != nil {
fmt.Printf("Timeout error: %v\n", err)
}NewFeature[T](executor func(resolve func(T), reject func(error))) *Feature[T]- Create new FeatureFeatureResolve[T](value T) *Feature[T]- Create resolved FeatureFeatureReject[T](err error) *Feature[T]- Create rejected FeatureThen(handler func(T) T) *Feature[T]- Chain success handlerCatch(handler func(error) T) *Feature[T]- Chain error handlerFinally(handler func()) *Feature[T]- Always execute handlerAwait() (T, error)- Wait for completionAwaitWithContext(ctx context.Context) (T, error)- Wait with timeoutFeatureAll[T](features ...*Feature[T]) *Feature[[]T]- Wait for allFeatureRace[T](features ...*Feature[T]) *Feature[T]- Return first completed
go test ./... # Run tests
go test -cover ./... # Run with coveragego-feature/
├── feature/
│ ├── feature.go # Core implementation
│ └── feature_test.go # Tests
├── main.go # Example usage
└── README.md
- Go 1.25.0+
MIT License - see LICENSE file for details.
- Fork the repository
- Create feature branch (
git checkout -b feature/NewFeature) - Commit changes (
git commit -m 'Add NewFeature') - Push to branch (
git push origin feature/NewFeature) - Open Pull Request