7

我需要的是async-await在 Svelte中使用onMount()

或者,也许您可​​以建议我出了什么问题以及我可以使用什么。

重现

  1. 去这里: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 中是否有其他方法可以做到这一点?

4

2 回答 2

10

只是为了解释为什么onMount不能成为一个async函数(这可能会在未来改变,但不要指望它):

onMount您可以从组件被销毁时调用的处理程序返回一个函数。但是async函数只能返回一个 promise。由于 Promise 不是函数,Svelte 将忽略返回值。

顺便说一下,这与 React 中的相同useEffect——函数必须是同步的,以避免竞争条件。推荐的解决方案与 foronMount相同——useEffect处理程序中放置一个async函数:

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

  foo();

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

(请注意,您有责任在承诺解决之前处理由于组件被破坏而出现的任何竞争条件,尽管在被破坏的组件内分配状态是无害的。)

我已经打开了一个问题来讨论在这些情况下提供更有用的反馈:https ://github.com/sveltejs/svelte/issues/4944

于 2020-05-31T15:27:03.353 回答
4

onMount必须是同步的。但是,您可以在标记和 make中使用{#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}

在这里查看我的工作示例。

这还有一个额外的好处是允许您使用加载器以及当 promise 被拒绝时出现的标记,使用以下语法:

{#await promise}
  loading
{:then value}
  loaded {value}
{:catch error}
  failed with {error}
{/await}
于 2020-05-29T13:47:54.740 回答