javascriptecmascript-6sveltesvelte-3svelte-component

Svelte 3, async onMount or a valid alternative?


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

  1. go here: https://svelte.dev/repl/000ae69c0fe14d9483678d4ace874726?version=3.23.0
  2. open the console
  3. click on the button
  4. you should see messages: "Mounting..." and "A lot of background work..."
  5. 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?


Solution

  • 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