问题
What I need is to use async-await
in Svelte onMount()
.
Or maybe you can suggest me what is wrong and what I can use alternatively.
To Reproduce
- go here: https://svelte.dev/repl/000ae69c0fe14d9483678d4ace874726?version=3.23.0
- open the console
- click on the button
- you should see messages:
"Mounting..."
and"A lot of background work..."
- if you click again the destroy message is not written
WHY?
Did onMount()
recognizes the async
function promise? Should it?
I need that async
behavior because I need to wait for function lazyLoading()
before rendering the Child
component.
Is there an alternative way to do this in Svelte?
回答1:
Just to explain why onMount
can't be an async
function (this might change in future, but don't expect it to):
You can return a function from an onMount
handler that is called when the component is destroyed. But async
functions can only return a promise. Since a promise isn't a function, Svelte will ignore the return value.
This is the same as useEffect
in React, incidentally — the function must be synchronous in order to avoid race conditions. The recommended solution for onMount
is the same as for useEffect
— place an async
function inside the handler:
onMount(() => {
async function foo() {
bar = await baz();
}
foo();
return () => console.log('destroyed');
});
(Note that you're responsible for handling any race conditions that arise as a result of the component being destroyed before the promise resolves, though assigning state inside a destroyed component is harmless.)
I've opened an issue to discuss providing more useful feedback in these situations: https://github.com/sveltejs/svelte/issues/4944
回答2:
onMount
must be synchronous. However, you can use an {#await} block in your markup and make lazyLoading
async
, for example:
{#await lazyLoading() then data}
I'm the child and I loaded "{data}".
{/await}
You could also do...
<script>
let dataPromise = lazyLoading()
</script>
{#await dataPromise then data}
I'm the child and I loaded "{data}".
{/await}
See my working example here.
This has the additional benefit of allowing you to use a loader as well as markup that appears when the promise is rejected, using this syntax:
{#await promise}
loading
{:then value}
loaded {value}
{:catch error}
failed with {error}
{/await}
来源:https://stackoverflow.com/questions/62087073/svelte-3-async-onmount-or-a-valid-alternative