Documentation
¶
Overview ¶
Package promise provides a generic, type-safe implementation of Promises, inspired by similar concepts in other languages like JavaScript. It is designed to simplify the management of asynchronous operations and avoid complex callback chains (often referred to as "callback hell").
Core Concepts ¶
A Promise represents the eventual completion (or failure) of an asynchronous operation and its resulting value. A Promise is always in one of three states:
- **pending**: The initial state; the asynchronous operation has not yet completed. - **fulfilled**: The operation completed successfully, and the promise now has a result value. - **rejected**: The operation failed, and the promise now holds an error.
Basic Usage ¶
The primary way to create a promise is with the `New` function, which takes an `executor` function. The executor is run in a new goroutine and is given `resolve` and `reject` functions to control the promise's final state.
// Create a promise that resolves with a message after a short delay.
p := promise.New(func(resolve func(string), reject func(error)) {
time.Sleep(100 * time.Millisecond)
resolve("Hello from the promise!")
})
// The Await method blocks until the promise is settled (either fulfilled or rejected).
val, err := p.Await()
// val will be "Hello from the promise!", err will be nil.
Chaining Asynchronous Operations ¶
Promises shine when you need to orchestrate a sequence of asynchronous steps. Methods like `Then`, `Catch`, and `Finally` allow you to build a clean, linear workflow.
Example of a complete chain:
// 1. Start an async operation to fetch a user ID.
userIDPromise := promise.Async(func() (int, error) {
fmt.Println("Fetching user ID...")
time.Sleep(50 * time.Millisecond)
return 123, nil // Simulate success
})
// 2. Use `Then` to fetch user data once the ID is available.
userDataPromise := promise.Then(userIDPromise, func(id int) (string, error) {
fmt.Printf("Fetching data for user %d...\n", id)
time.Sleep(50 * time.Millisecond)
return fmt.Sprintf("{\"name\": \"Alice\", \"id\": %d}", id), nil
})
// 3. Use `Catch` to handle any errors that might have occurred in the chain.
finalPromise := promise.Catch(userDataPromise, func(err error) (string, error) {
fmt.Printf("An error occurred: %v. Recovering.\n", err)
return "default data", nil // Recover with a default value
})
// 4. Await the final result.
finalResult, _ := finalPromise.Await()
fmt.Printf("Final result: %s\n", finalResult)
This creates a readable, non-blocking sequence of dependent operations.
Index ¶
- func Await[T any](p *Promise[T]) (T, error)
- type Promise
- func (p *Promise[T]) Await() (T, error)
- func (p *Promise[T]) Catch(onRejected func(error) (T, error)) *Promise[T]
- func (p *Promise[T]) Finally(onFinally func()) *Promise[T]
- func (p *Promise[T]) Reject(err error)
- func (p *Promise[T]) Resolve(value T)
- func (p *Promise[T]) Then(onFulfilled func(T) T) *Promise[T]
- func (p *Promise[T]) ThenWithPromise(onFulfilled func(T) *Promise[T]) *Promise[T]
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Promise ¶
type Promise[T any] struct { // contains filtered or unexported fields }
Promise represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It is a generic, type-safe implementation inspired by the JavaScript Promise API.
func Async ¶
Async is a helper function that wraps a function returning (T, error) into a new Promise. This is useful for converting existing functions into promise-based asynchronous operations.
func New ¶
New creates a new Promise. The provided executor function is executed in a new goroutine. The executor receives `resolve` and `reject` functions to control the promise's outcome.
func (*Promise[T]) Await ¶
Await blocks until the promise is settled and returns the resulting value and error. It is the primary way to get the result of a promise.
func (*Promise[T]) Catch ¶
Catch attaches a callback that executes when the promise is rejected. It allows for error handling and recovery. The onRejected callback can return a new value to fulfill the promise, or a new error to continue the rejection chain.
func (*Promise[T]) Finally ¶
Finally attaches a callback that executes when the promise is settled (either fulfilled or rejected). It is useful for cleanup logic. The returned promise will be settled with the same value or error as the original promise, after onFinally has completed.
func (*Promise[T]) Reject ¶
Reject rejects the promise with an error. If the promise is already settled, this call is ignored.
func (*Promise[T]) Resolve ¶
func (p *Promise[T]) Resolve(value T)
Resolve fulfills the promise with a value. If the promise is already settled, this call is ignored.
func (*Promise[T]) Then ¶
Then attaches a callback that executes when the promise is fulfilled. It returns a new promise that resolves with the result of the onFulfilled callback. If the original promise is rejected, the new promise is rejected with the same error.
func (*Promise[T]) ThenWithPromise ¶
ThenWithPromise is like Then, but the callback returns a new Promise. This allows for chaining of asynchronous operations.