pub struct Resource<S, T>where
S: 'static,
T: 'static,{ /* private fields */ }
Expand description
A signal that reflects the
current state of an asynchronous task, allowing you to integrate async
Future
s into the synchronous reactive system.
Takes a fetcher
function that generates a Future
when called and a
source
signal that provides the argument for the fetcher
. Whenever the
value of the source
changes, a new Future
will be created and run.
When server-side rendering is used, the server will handle running the
Future
and will stream the result to the client. This process requires the
output type of the Future to be Serializable
. If your output cannot be
serialized, or you just want to make sure the Future
runs locally, use
create_local_resource()
.
// any old async function; maybe this is calling a REST API or something
async fn fetch_cat_picture_urls(how_many: i32) -> Vec<String> {
// pretend we're fetching cat pics
vec![how_many.to_string()]
}
// a signal that controls how many cat pics we want
let (how_many_cats, set_how_many_cats) = create_signal(1);
// create a resource that will refetch whenever `how_many_cats` changes
let cats = create_resource(move || how_many_cats.get(), fetch_cat_picture_urls);
// when we read the signal, it contains either
// 1) None (if the Future isn't ready yet) or
// 2) Some(T) (if the future's already resolved)
assert_eq!(cats.get(), Some(vec!["1".to_string()]));
// when the signal's value changes, the `Resource` will generate and run a new `Future`
set_how_many_cats.set(2);
assert_eq!(cats.get(), Some(vec!["2".to_string()]));
We can provide single, multiple or even a non-reactive signal as source
// Single signal. `Resource` will run once initially and then every time `how_many_cats` changes
let async_data = create_resource(move || how_many_cats.get() , |_| async move { todo!() });
// Non-reactive signal. `Resource` runs only once
let async_data = create_resource(|| (), |_| async move { todo!() });
// Multiple signals. `Resource` will run once initially and then every time `how_many_cats` or `how_many_dogs` changes
let async_data = create_resource(move || (how_many_cats.get(), how_many_dogs.get()), |_| async move { todo!() });
Implementations§
source§impl<S, T> Resource<S, T>where
S: Clone + 'static,
T: 'static,
impl<S, T> Resource<S, T>where
S: Clone + 'static,
T: 'static,
sourcepub fn read(&self) -> Option<T>where
T: Clone,
👎Deprecated: You can now use .get() on resources.
pub fn read(&self) -> Option<T>where
T: Clone,
Clones and returns the current value of the resource (Option::None if the resource is still pending). Also subscribes the running effect to this resource.
If you want to get the value without cloning it, use Resource::with
.
(value.read()
is equivalent to value.with(T::clone)
.)
sourcepub fn map<U>(&self, f: impl FnOnce(&T) -> U) -> Option<U>
pub fn map<U>(&self, f: impl FnOnce(&T) -> U) -> Option<U>
Applies a function to the current value of the resource, and subscribes
the running effect to this resource. If the resource hasn’t yet
resolved, the function won’t be called and this will return
Option::None
.
If you want to get the value by cloning it, you can use
Resource::read
.
source§impl<S, T, E> Resource<S, Result<T, E>>
impl<S, T, E> Resource<S, Result<T, E>>
sourcepub fn and_then<U>(&self, f: impl FnOnce(&T) -> U) -> Option<Result<U, E>>
pub fn and_then<U>(&self, f: impl FnOnce(&T) -> U) -> Option<Result<U, E>>
Applies the given function when a resource that returns Result<T, E>
has resolved and loaded an Ok(_)
, rather than requiring nested .map()
calls over the Option<Result<_, _>>
returned by the resource.
This is useful when used with features like server functions, in conjunction
with <ErrorBoundary/>
and <Suspense/>
, when these other components are
left to handle the None
and Err(_)
states.
let cats = create_resource(
|| (),
|_| async { Ok(vec![0, 1, 2]) as Result<Vec<i32>, ()> },
);
create_effect(move |_| {
cats.and_then(|data: &Vec<i32>| println!("{}", data.len()));
});
source§impl<S, T> Resource<S, T>where
S: 'static,
T: 'static,
impl<S, T> Resource<S, T>where
S: 'static,
T: 'static,
sourcepub fn new<Fu>(
source: impl Fn() -> S + 'static,
fetcher: impl Fn(S) -> Fu + 'static,
) -> Resource<S, T>
pub fn new<Fu>( source: impl Fn() -> S + 'static, fetcher: impl Fn(S) -> Fu + 'static, ) -> Resource<S, T>
Creates a Resource
, which is a signal that reflects the
current state of an asynchronous task, allowing you to integrate async
Future
s into the synchronous reactive system.
Takes a fetcher
function that generates a Future
when called and a
source
signal that provides the argument for the fetcher
. Whenever the
value of the source
changes, a new Future
will be created and run.
When server-side rendering is used, the server will handle running the
Future
and will stream the result to the client. This process requires the
output type of the Future to be Serializable
. If your output cannot be
serialized, or you just want to make sure the Future
runs locally, use
create_local_resource()
.
This is identical with create_resource
.
// any old async function; maybe this is calling a REST API or something
async fn fetch_cat_picture_urls(how_many: i32) -> Vec<String> {
// pretend we're fetching cat pics
vec![how_many.to_string()]
}
// a signal that controls how many cat pics we want
let (how_many_cats, set_how_many_cats) = create_signal(1);
// create a resource that will refetch whenever `how_many_cats` changes
let cats = Resource::new(move || how_many_cats.get(), fetch_cat_picture_urls);
// when we read the signal, it contains either
// 1) None (if the Future isn't ready yet) or
// 2) Some(T) (if the future's already resolved)
assert_eq!(cats.get(), Some(vec!["1".to_string()]));
// when the signal's value changes, the `Resource` will generate and run a new `Future`
set_how_many_cats.set(2);
assert_eq!(cats.get(), Some(vec!["2".to_string()]));
sourcepub fn local<Fu>(
source: impl Fn() -> S + 'static,
fetcher: impl Fn(S) -> Fu + 'static,
) -> Resource<S, T>
pub fn local<Fu>( source: impl Fn() -> S + 'static, fetcher: impl Fn(S) -> Fu + 'static, ) -> Resource<S, T>
Creates a local Resource
, which is a signal that
reflects the current state of an asynchronous task, allowing you to
integrate async
Future
s into the synchronous reactive system.
Takes a fetcher
function that generates a Future
when called and a
source
signal that provides the argument for the fetcher
. Whenever the
value of the source
changes, a new Future
will be created and run.
Unlike create_resource()
, this Future
is always run on the local system
and therefore it’s result type does not need to be Serializable
.
This is identical with create_local_resource
.
#[derive(Debug, Clone)] // doesn't implement Serialize, Deserialize
struct ComplicatedUnserializableStruct {
// something here that can't be serialized
}
// any old async function; maybe this is calling a REST API or something
async fn setup_complicated_struct() -> ComplicatedUnserializableStruct {
// do some work
ComplicatedUnserializableStruct {}
}
// create the resource; it will run but not be serialized
let result =
create_local_resource(move || (), |_| setup_complicated_struct());
source§impl<T> Resource<(), T>where
T: 'static,
impl<T> Resource<(), T>where
T: 'static,
sourcepub fn once<Fu>(fetcher: impl Fn() -> Fu + 'static) -> Resource<(), T>where
T: Serializable + 'static,
Fu: Future<Output = T> + 'static,
pub fn once<Fu>(fetcher: impl Fn() -> Fu + 'static) -> Resource<(), T>where
T: Serializable + 'static,
Fu: Future<Output = T> + 'static,
Creates a resource that will only load once, and will not respond to any reactive changes, including changes in any reactive variables read in its fetcher.
This identical to create_resource(|| (), move |_| fetcher())
.
Trait Implementations§
source§impl<S, T> SignalDispose for Resource<S, T>where
S: 'static,
T: 'static,
impl<S, T> SignalDispose for Resource<S, T>where
S: 'static,
T: 'static,
source§impl<S, T> SignalGet for Resource<S, T>
impl<S, T> SignalGet for Resource<S, T>
source§impl<S, T> SignalUpdate for Resource<S, T>
impl<S, T> SignalUpdate for Resource<S, T>
source§impl<S, T> SignalWith for Resource<S, T>where
S: Clone,
impl<S, T> SignalWith for Resource<S, T>where
S: Clone,
impl<S, T> Copy for Resource<S, T>where
S: 'static,
T: 'static,
impl<S, T> Eq for Resource<S, T>
impl<S, T> StructuralPartialEq for Resource<S, T>where
S: 'static,
T: 'static,
Auto Trait Implementations§
impl<S, T> Freeze for Resource<S, T>
impl<S, T> RefUnwindSafe for Resource<S, T>where
S: RefUnwindSafe,
T: RefUnwindSafe,
impl<S, T> Send for Resource<S, T>
impl<S, T> Sync for Resource<S, T>
impl<S, T> Unpin for Resource<S, T>
impl<S, T> UnwindSafe for Resource<S, T>where
S: UnwindSafe,
T: UnwindSafe,
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
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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>
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>
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 more