-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Await expressions #1857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This would make a lot of things easier, especially around lazy-loading. One question: This would only ever run on the client, and not in SSR, correct? |
With the current SSR process, yeah. I'd like to look into ways we could accommodate async/streaming SSR in v3 though |
@Rich-Harris Your |
D'oh. Fixed |
I really like this. I tend to work with promises a lot and this would make most of my use cases a lot cleaner and easier. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I was just looking over the docs today for inline awaits. I am predominantly an Angular developer and am used to this syntax in the templates (html)
I'm currently writing some Svelte UI code that right now looks like this:
Ignoring the over-verbosity of my class/method names, inline await would make this much nicer to work with, are pipes a possibility at all in Svelte? |
O more general solution would be to leverage the pipe syntax like rohan suggests. This would make it possible to provide other features besides await and users would be able to provide custom ones themselves. |
Moving forward I'd rather see When I started with Svelte I briefly used Another limitation is that you are forced into the syntax of the I personally abstract everything away into stores. Stores are amazing. With everything I mean things like import { readable } from 'svelte/store';
export const fibonacci = function (n, initialData) {
return readable(
{
loading: true,
error: null,
data: initialData,
},
(set) => {
let controller = new AbortController();
(async () => {
try {
let result = await fibonacciWorker.calculate(n, {
signal: controller.signal
});
set({
loading: false,
error: null,
data: result,
});
} catch (err) {
// Ignore AbortErrors, they're not unexpected but a feature.
// In case of abortion we just keep the loading state because another request is on its way anyway.
if (err.name !== 'AbortError') {
set({
loading: false,
error: err,
data: initialData,
});
}
}
})();
return () => {
controller.abort();
};
}
);
}; <script>
import { fibonacci } from './math.js';
$: result = fibonacci(n, 0);
</script>
<input type=number bind:value={n}>
<p>The {n}th Fibonacci number is {$result.data}</p>
{#if $result.loading}
<p>Show a spinner, add class or whatever you need.</p>
<p>You are not limited to the syntax of an #await block. You are free to do whatever you want.</p>
{/if} Like I said, that's just from my experience. Maybe Svelte can either offer a way to turn promises into stores or advocate this in user land. I'm using this with great success. No need to debounce Once you've written the imperative library/util code once, your components are super slim and completely reactive/declarative. Wow. Edit: For people that want the existing semantics (without aborting) but with a store API maybe Svelte could add this: <script>
import { fromPromise } from 'svelte/store';
$: result = fromPromise(fibonacciWorker.calculate(n), 0);
</script>
<input type=number bind:value={n}>
<p>The {n}th Fibonacci number is {$result.data}</p> Yes I love stores. |
At Square we've followed a similar route as @Prinzhorn in the abundant usage of stores to solve more complicated versions of this problem. We have developed some patterns in the @square/svelte-store package with custom stores that help drastically reduce the amount of boilerplate required to accomplish similar tasks. I've spun up a suite of examples here: https://codesandbox.io/s/solving-async-problems-with-stores-kr712b Taking this approach lets you use both #await and state-based conditional rendering, depending on the exact use case. Having access to a promise becomes very useful when you start dealing with more complicated flows of asynchronous data, such as when you want to fetch asynchronous data based on other asynchronous data However if you don't need this level of control all of this is much heavier than the proposed inline {await} Something that might additionally be helpful is allowing users to
But it would be nice to be able to just do this!
|
Uh oh!
There was an error while loading. Please reload this page.
Just want to capture a thought I had the other day: it might be neat to have inline
await
expressions in templates. We already have{#await ...}
blocks but they're overkill in some situations — you have to declare a name for the resolved value, which you might only be using once, and you might not need to worry about error states depending on what you're doing.Imagine something like this (v3 syntax):
It would integrate with Suspense, so it'd be convenient for doing this sort of thing (where
loadImage
resolves to its input, but only after ensuring that the image is loaded):Of course, you'd need some way to have placeholder content, for situations where you're not using Suspense. Maybe this?
The text was updated successfully, but these errors were encountered: