Svelte 3, asyn c onMount или допустимая альтернатива? - PullRequest
4 голосов
/ 29 мая 2020

Мне нужно использовать async-await в Svelte onMount().

Или, может быть, вы можете предложить мне, что не так и что я могу использовать в качестве альтернативы.

Чтобы воспроизвести

  1. go здесь: https://svelte.dev/repl/000ae69c0fe14d9483678d4ace874726?version=3.23.0
  2. откройте консоль
  3. нажмите кнопка
  4. вы должны увидеть сообщения: "Mounting..." и "A lot of background work..."
  5. , если вы нажмете еще раз, сообщение об уничтожении не будет записано

ПОЧЕМУ?

Распознает ли onMount() обещание функции async? Должно ли это?

Мне нужно это async поведение, потому что мне нужно дождаться function lazyLoading() перед рендерингом компонента Child.

Есть ли альтернативный способ сделать это в Svelte?

Ответы [ 2 ]

3 голосов
/ 29 мая 2020

onMount должно быть синхронным. Однако вы можете использовать и {#await} блок в своей разметке и сделать lazyLoading async, например:

{#await lazyLoading() then data}
  I'm the child and I loaded "{data}".
{/await}

Вы также можете сделать ...

<script>
  let dataPromise = lazyLoading()
</script>

{#await dataPromise then data}
  I'm the child and I loaded "{data}".
{/await}

См. Мой рабочий пример здесь .

Это дает дополнительное преимущество, позволяя вам использовать загрузчик, а также разметку, которая появляется, когда обещание отклоняется, используя это синтаксис:

{#await promise}
  loading
{:then value}
  loaded {value}
{:catch error}
  failed with {error}
{/await}
2 голосов
/ 31 мая 2020

Просто чтобы объяснить, почему onMount не может быть функцией async (это может измениться в будущем, но не ожидайте этого):

Вы можете вернуть функция из обработчика onMount, которая вызывается при уничтожении компонента. Но функции async могут возвращать только обещание . Поскольку обещание не является функцией, Svelte проигнорирует возвращаемое значение.

Это то же самое, что useEffect в React, кстати - функция должна быть синхронной, чтобы избежать состояния гонки. Рекомендуемое решение для onMount такое же, как для useEffect - поместите async функцию внутри обработчика:

onMount(() => {
  async function foo() {
    bar = await baz();
  }

  foo();

  return () => console.log('destroyed');
});

(обратите внимание, что вы несете ответственность за обработку любые состояния гонки, возникающие в результате уничтожения компонента до разрешения обещания, хотя назначение состояния внутри уничтоженного компонента безвредно.)

Я открыл проблему, чтобы обсудить предоставление более полезной обратной связи в этих ситуациях : https://github.com/sveltejs/svelte/issues/4944

...