promise

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 24, 2025 License: MIT Imports: 2 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func Await

func Await[T any](p *Promise[T]) (T, error)

Await is a standalone function that waits for a promise to be settled. It is a functional equivalent of the p.Await() method.

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 All added in v0.11.0

func All[T any](ps ...*Promise[T]) *Promise[[]T]

All creates a new Promise that resolves when all the provided promises have resolved.

Parameters:

ps: a slice of Promise objects to be resolved

Returns:

A new Promise object that resolves with a slice of values from the input promises

Notes:

  1. If any of the input promises is rejected, the returned promise is immediately rejected with the same error
  2. The order of the values in the resolved slice corresponds to the order of the input promises

func Async

func Async[T any](f func() (T, error)) *Promise[T]

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

func New[T any](executor func(resolve func(T), reject func(error))) *Promise[T]

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 Then added in v0.11.0

func Then[T, K any](p1 *Promise[T], f func(val T) (K, error)) *Promise[K]

Then chains a transformation to the result of a Promise.

Parameters:

p1: the input Promise object
f: transformation function that takes p1's result and returns a new value or error

Returns:

A new Promise object with the result of the transformation function f

Notes:

  1. If p1 returns an error, it is directly propagated
  2. If a panic occurs in the transformation function f, it is caught and converted to an error
  3. If the transformation function f returns an error, it is propagated

func (*Promise[T]) Await

func (p *Promise[T]) Await() (T, error)

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

func (p *Promise[T]) Catch(onRejected func(error) (T, error)) *Promise[T]

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

func (p *Promise[T]) Finally(onFinally func()) *Promise[T]

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]) Then

func (p *Promise[T]) Then(onFulfilled func(T) T) *Promise[T]

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

func (p *Promise[T]) ThenWithPromise(onFulfilled func(T) *Promise[T]) *Promise[T]

ThenWithPromise is like Then, but the callback returns a new Promise. This allows for chaining of asynchronous operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL