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 typeT
.State::Rejected(E)
: the operation failed with an error of typeE
.
§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:
Promise::resolve
returns a promise that is immediately fulfilled.Promise::reject
returns a promise that is immediately rejected.
§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>
impl<T, E> Promise<T, E>
Sourcepub fn new<'a>(
executor: impl FnOnce(Box<dyn FnOnce(T) + Send + 'a>, Box<dyn FnOnce(E) + Send + 'a>) + 'a,
) -> Self
pub fn new<'a>( executor: impl FnOnce(Box<dyn FnOnce(T) + Send + 'a>, Box<dyn FnOnce(E) + Send + 'a>) + 'a, ) -> Self
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));
Sourcepub fn resolve(value: T) -> Self
pub fn resolve(value: T) -> Self
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));
Sourcepub fn reject(error: E) -> Self
pub fn reject(error: E) -> Self
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"));
Sourcepub fn state(&self) -> State<T, E>
pub fn state(&self) -> State<T, E>
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));
Sourcepub fn then<U>(
self,
on_fulfilled: impl FnOnce(T) -> U + Send + 'static,
) -> Promise<U, E>
pub fn then<U>( self, on_fulfilled: impl FnOnce(T) -> U + Send + 'static, ) -> Promise<U, E>
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));
Sourcepub fn catch<F>(
self,
on_rejected: impl FnOnce(E) -> F + Send + 'static,
) -> Promise<T, F>
pub fn catch<F>( self, on_rejected: impl FnOnce(E) -> F + Send + 'static, ) -> Promise<T, F>
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()));
Sourcepub fn finally(
self,
on_finally: impl FnOnce() + Send + 'static,
) -> Promise<T, E>
pub fn finally( self, on_finally: impl FnOnce() + Send + 'static, ) -> Promise<T, E>
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);
Sourcepub fn all(
promises: impl IntoIterator<Item = Promise<T, E>> + 'static,
) -> Promise<Vec<T>, E>
pub fn all( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<Vec<T>, E>
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!(),
}
Sourcepub fn allSettled(
promises: impl IntoIterator<Item = Promise<T, E>> + 'static,
) -> Promise<Vec<State<T, E>>, ()>
pub fn allSettled( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<Vec<State<T, E>>, ()>
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!(),
}
Sourcepub fn any(
promises: impl IntoIterator<Item = Promise<T, E>> + 'static,
) -> Promise<T, Vec<E>>
pub fn any( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<T, Vec<E>>
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));
Sourcepub fn race(
promises: impl IntoIterator<Item = Promise<T, E>> + 'static,
) -> Promise<T, E>
pub fn race( promises: impl IntoIterator<Item = Promise<T, E>> + 'static, ) -> Promise<T, E>
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));