Promise

Struct Promise 

Source
pub struct Promise<T, E> { /* private fields */ }
Expand description

A Promise represents the eventual outcome of an asynchronous operation, similar to JavaScript’s Promise. It may be in one of three states:

  • State::Pending: the operation is still in progress.
  • State::Fulfilled(T): the operation completed successfully with a value of type T.
  • State::Rejected(E): the operation failed with an error of type E.

§Creating Promises

A new promise is created using Promise::new, which accepts an executor function that receives resolve and reject callbacks to settle the promise. Additionally, helper functions are provided:

§Chaining and Error Handling

Once a promise is created, you can:

  • Chain further operations with Promise::then, which runs when the promise is fulfilled.
  • Handle errors using Promise::catch, which runs when the promise is rejected.
  • Execute side effects regardless of the outcome using Promise::finally.

§Combinators

For coordinating multiple promises, several methods are available:

  • Promise::all waits until every promise fulfills (or rejects early if any reject),
  • Promise::allSettled waits for all promises to settle and returns their states,
  • Promise::any fulfills as soon as any promise fulfills (or rejects with all errors),
  • Promise::race settles as soon as any promise settles.

§Example

use rsvow::{Promise, State};

// Create a promise that resolves immediately with 42.
let promise: Promise<i32, ()> = Promise::resolve(42);

// Chain a `then` callback to double the value.
let doubled = promise.then(|value| value * 2);

// Check the result.
assert_eq!(doubled.state(), State::Fulfilled(84));

This struct provides a flexible, chainable interface for asynchronous tasks, enabling the composition of complex asynchronous workflows in a declarative style.

Implementations§

Source§

impl<T, E> Promise<T, E>

Source

pub fn new<'a>( executor: impl FnOnce(Box<dyn FnOnce(T) + Send + 'a>, Box<dyn FnOnce(E) + Send + 'a>) + 'a, ) -> Self
where T: Send + 'a, E: Send + 'a,

Creates a new Promise using the provided executor function.

The executor receives resolve and reject closures to settle the promise.

This is equivalent to the JavaScript Promise constructor.

§Example
use rsvow::{Promise, State};

let promise: Promise<i32, ()> = Promise::new(|resolve, _reject| {
    resolve(42);
});
assert_eq!(promise.state(), State::Fulfilled(42));

Multithreaded example:

use rsvow::{Promise, State};
use std::thread;

let promise: Promise<u8, bool> = Promise::new(|_resolve, reject| {
   thread::spawn(move || {
      thread::sleep(std::time::Duration::from_millis(20));
      reject(true);
  });
});
assert_eq!(promise.state(), State::Pending);
thread::sleep(std::time::Duration::from_millis(200));
assert_eq!(promise.state(), State::Rejected(true));
Source

pub fn resolve(value: T) -> Self
where T: Send, E: Send,

Immediately resolves a promise with the given value.

§Example
use rsvow::{Promise, State};

let promise: Promise<i32, ()> = Promise::resolve(42);
assert_eq!(promise.state(), State::Fulfilled(42));
Source

pub fn reject(error: E) -> Self
where T: Send, E: Send,

Immediately rejects a promise with the given error.

§Example
use rsvow::{Promise, State};
let promise: Promise<(), &str> = Promise::reject("error");
assert_eq!(promise.state(), State::Rejected("error"));
Source

pub fn state(&self) -> State<T, E>
where T: Clone, E: Clone,

Returns the current state of the promise.

This intended to be used for testing and debugging purposes. No equivalent exists in JavaScript.

§Example
use rsvow::{Promise, State};

let promise: Promise<i32, ()> = Promise::resolve(-1);
assert_eq!(promise.state(), State::Fulfilled(-1));
Source

pub fn then<U>( self, on_fulfilled: impl FnOnce(T) -> U + Send + 'static, ) -> Promise<U, E>
where T: Send + 'static, U: Send + 'static, E: Send + 'static,

Chains a callback executed when the promise is fulfilled.

If the promise is fulfilled, on_fulfilled is called with the value. Otherwise, the rejection is passed through.

§Example
use rsvow::{Promise, State};

let promise: Promise<u64, String> = Promise::resolve(10).then(|v| v * 2);
assert_eq!(promise.state(), State::Fulfilled(20));
Source

pub fn catch<F>( self, on_rejected: impl FnOnce(E) -> F + Send + 'static, ) -> Promise<T, F>
where T: Send + 'static, F: Send + 'static, E: Send + 'static,

Catches a rejection from the promise and transforms the error.

If the promise is rejected, on_rejected is called with the error. Fulfilled promises pass the value along.

§Example
use rsvow::{Promise, State};

let promise: Promise<(), String> = Promise::reject("error").catch(|e| format!("{}!", e));
assert_eq!(promise.state(), State::Rejected("error!".to_string()));
Source

pub fn finally( self, on_finally: impl FnOnce() + Send + 'static, ) -> Promise<T, E>
where T: Send + 'static, E: Send + 'static,

Executes a callback when the promise is settled (fulfilled or rejected).

The callback is executed regardless of the outcome.

§Example
use rsvow::{Promise, State};
use std::sync::{Arc, Mutex};

let flag = Arc::new(Mutex::new(false));
let flag_clone = flag.clone();

let promise: Promise<u16, ()> = Promise::resolve(42).finally(move || {
    *flag_clone.lock().unwrap() = true;
});
assert_eq!(promise.state(), State::Fulfilled(42));
assert_eq!(*flag.lock().unwrap(), true);
Source

pub fn all( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<Vec<T>, E>
where T: Send + 'static, E: Send + 'static,

Waits for all promises to fulfill or rejects once any promise is rejected.

Returns a promise that fulfills with a vector of all values or rejects immediately.

§Example
use rsvow::{Promise, State};

let p1 = Promise::resolve(1);
let p2 = Promise::resolve(2);
let p3 = Promise::resolve(3);

let all: Promise<Vec<u8>, ()> = Promise::all(vec![p1, p2, p3]);
match all.state() {
   State::Fulfilled(mut values) => {
      values.sort();
      assert_eq!(values, vec![1, 2, 3]);
  },
 _ => unreachable!(),
}
Source

pub fn allSettled( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<Vec<State<T, E>>, ()>
where T: Send + 'static, E: Send + 'static,

Waits for all promises to settle and returns a promise with an array of their states.

§Example
use rsvow::{Promise, State};

let p1: Promise<i8, &str> = Promise::resolve(1);
let p2: Promise<i8, &str> = Promise::reject("error");

let all_settled = Promise::allSettled(vec![p1, p2]);
match all_settled.state() {
    State::Fulfilled(results) => {
        assert!(results.iter().any(|r| matches!(r, State::Fulfilled(1))));
        assert!(results.iter().any(|r| matches!(r, State::Rejected("error"))));
    },
    _ => unreachable!(),
}
Source

pub fn any( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<T, Vec<E>>
where T: Send + 'static, E: Send + 'static,

Resolves as soon as any promise is fulfilled, or rejects with a list of errors if all reject.

§Example
use rsvow::{Promise, State};

let p1 = Promise::reject(0);
let p2 = Promise::resolve(42);
let p3 = Promise::reject(1);

let any: Promise<usize, Vec<i8>> = Promise::any(vec![p1, p2, p3]);
assert_eq!(any.state(), State::Fulfilled(42));
Source

pub fn race( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<T, E>
where T: Send + 'static, E: Send + 'static,

Settles as soon as any promise resolves or rejects, adopting that value.

§Example
use rsvow::{Promise, State};

let p1: Promise<isize, ()> = Promise::new(|_resolve, _reject| {});
let p2 = Promise::resolve(42);

let race = Promise::race(vec![p1, p2]);
assert_eq!(race.state(), State::Fulfilled(42));

Trait Implementations§

Source§

impl<T: Debug, E: Debug> Debug for Promise<T, E>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: PartialEq, E: PartialEq> PartialEq for Promise<T, E>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<T, E> Freeze for Promise<T, E>

§

impl<T, E> RefUnwindSafe for Promise<T, E>

§

impl<T, E> Send for Promise<T, E>
where T: Send, E: Send,

§

impl<T, E> Sync for Promise<T, E>
where T: Send, E: Send,

§

impl<T, E> Unpin for Promise<T, E>

§

impl<T, E> UnwindSafe for Promise<T, E>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.