|
Essentially the question is if there is an option to make an async derived resolve immediately and update later with the value of the resolved promise. Currently I use this: <script>
// some promise for example from load function
let promise = $state(new Promise(() => {}));
// initially undefined
let data = $state();
// update the data when the promise resolves and also when the promise changes
$effect(() => {
promise.then((newData) => (data = newData));
});
</script>Because when I try to use async derived it blocks until the promise resolves and i don't want to wait to render the UI until the data is loaded: <script>
// some promise for example from load function
let promise = $state(new Promise(() => {}));
// blocks forever in this case because the promise never resolves
let data = $derived(await promise);
</script>Is there a way to give derived a default value sort of like this? <script>
// some promise for example from load function
let promise = $state(new Promise(() => {}));
// resolves instantly to undefined and gets updated later when the actual promise resolves
let data = $derived(await promise, undefined);
</script>There is also this solution from shadcn svelte extra but it is still not as clean as builtin way |
Replies: 2 comments
|
No built-in option for this right now. Your The If you find yourself repeating this pattern, you could extract it: function lazyAsync(fn) {
let value = $state();
$effect(() => {
fn().then(v => value = v);
});
return () => value;
}
// usage
const data = lazyAsync(() => promise);
// read with data()But honestly for a one-off, your current code is fine and readable. There's been some discussion in the Svelte community about whether |
|
I'd be wary of mutating state in your You can just pass the <script lang='ts'>
let propInput = $state(10)
const myAsyncFunction = async (input: number) => {
return await new Promise<number>((res) => setTimeout(() => res(input), 2000));
};
let value = $derived(myAsyncFunction(propInput));
</script>
<div>
{await value}
</div>the playground example shows you can still rerun/temp override the derived. https://svelte.dev/playground/a8381ac868c443adba7cfb8091d85e9b?version=5.56.3 I will say that I have had trouble with creating deep proxies of the derived, if for example your promise resolves to an array. |
No built-in option for this right now. Your
$effect+$statecombo is the intended way to handle "render immediately, update when ready."The
awaitin$derivedis designed to block on purpose — it guarantees the value is always resolved when you read it, which is useful but obviously not what you want when you need to show a loading state.If you find yourself repeating this pattern, you could extract it:
But honestly for a one-off, your current code is fine and readable. There's been some discu…