pub struct JsFuture<T> { /* private fields */ }
Available on crate features
napi-5
and futures
only.Expand description
A type of JavaScript
Promise
object that acts as a Future
.
Unlike typical Future
implementations, JsFuture
s are eagerly executed
because they are backed by a Promise
.
§Example
This example uses a JsFuture
to take asynchronous binary data and perform
potentially expensive computations on that data in a Rust thread.
The example uses a Tokio thread pool (allocated and
stored on demand with a OnceCell
)
to run the computations.
use neon::types::buffer::TypedArray;
use once_cell::sync::OnceCell;
use tokio::runtime::Runtime;
// Lazily allocate a Tokio runtime to use as the thread pool.
fn runtime(cx: &mut Cx) -> NeonResult<&'static Runtime> {
static RUNTIME: OnceCell<Runtime> = OnceCell::new();
RUNTIME
.get_or_try_init(Runtime::new)
.or_else(|err| cx.throw_error(&err.to_string()))
}
// async_compute: Promise<Float64Array> -> Promise<number>
//
// Takes a promise that produces a typed array and returns a promise that:
// - awaits the typed array from the original promise;
// - computes a value from the contents of the array in a background thread; and
// - resolves once the computation is completed
pub fn async_compute(mut cx: FunctionContext) -> JsResult<JsPromise> {
let nums: Handle<JsPromise> = cx.argument(0)?;
// Convert the JS Promise to a Rust Future for use in a compute thread.
let nums = nums.to_future(&mut cx, |mut cx, result| {
// Get the promise's result value (or throw if it was rejected).
let value = result.or_throw(&mut cx)?;
// Downcast the result value to a Float64Array.
let array: Handle<JsFloat64Array> = value.downcast_or_throw(&mut cx)?;
// Convert the typed array to a Rust vector.
let vec = array.as_slice(&cx).to_vec();
Ok(vec)
})?;
// Construct a result promise which will be fulfilled when the computation completes.
let (deferred, promise) = cx.promise();
let channel = cx.channel();
let runtime = runtime(&mut cx)?;
// Perform the computation in a background thread using the Tokio thread pool.
runtime.spawn(async move {
// Await the JsFuture, which yields Result<Vec<f64>, JoinError>.
let result = match nums.await {
// Perform the computation. In this example, we just calculate the sum
// of all values in the array; more involved examples might be running
// compression or decompression algorithms, encoding or decoding media
// codecs, image filters or other media transformations, etc.
Ok(nums) => Ok(nums.into_iter().sum::<f64>()),
Err(err) => Err(err)
};
// Resolve the result promise with the result of the computation.
deferred.settle_with(&channel, |mut cx| {
let result = result.or_throw(&mut cx)?;
Ok(cx.number(result))
});
});
Ok(promise)
}
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for JsFuture<T>
impl<T> !RefUnwindSafe for JsFuture<T>
impl<T> Send for JsFuture<T>where
T: Send,
impl<T> Sync for JsFuture<T>where
T: Send,
impl<T> Unpin for JsFuture<T>
impl<T> !UnwindSafe for JsFuture<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<F> IntoFuture for Fwhere
F: Future,
impl<F> IntoFuture for Fwhere
F: Future,
Source§type IntoFuture = F
type IntoFuture = F
Which kind of future are we turning this into?
Source§fn into_future(self) -> <F as IntoFuture>::IntoFuture
fn into_future(self) -> <F as IntoFuture>::IntoFuture
Creates a future from a value. Read more