简体   繁体   English

Svelte 3、async onMount 还是有效的替代方案?

[英]Svelte 3, async onMount or a valid alternative?

What I need is to use async-await in Svelte onMount() .我需要的是在 Svelte onMount()中使用async-await

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 go 这里: 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..."您应该看到消息: "Mounting...""A lot of background work..."
  5. if you click again the destroy message is not written如果您再次单击,则不会写入销毁消息

WHY?为什么?

Did onMount() recognizes the async function promise? onMount()是否识别async function promise? Should it?应该是?

I need that async behavior because I need to wait for function lazyLoading() before rendering the Child component.我需要这种async行为,因为在渲染Child组件之前我需要等待function lazyLoading()

Is there an alternative way to do this in Svelte?在 Svelte 中是否有其他方法可以做到这一点?

Just to explain why onMount can't be an async function (this might change in future, but don't expect it to):只是为了解释为什么onMount不能是async function(这可能会在未来改变,但不要指望它会):

You can return a function from an onMount handler that is called when the component is destroyed.您可以从销毁组件时调用的onMount处理程序返回 function。 But async functions can only return a promise .但是async函数只能返回 promise Since a promise isn't a function, Svelte will ignore the return value.由于 promise 不是 function,Svelte 将忽略返回值。

This is the same as useEffect in React, incidentally — the function must be synchronous in order to avoid race conditions.这与 React 中的useEffect相同,顺便说一句 - function 必须同步以避免竞争条件。 The recommended solution for onMount is the same as for useEffect — place an async function inside the handler: onMount 的推荐解决方案与onMount相同——处理程序中放置一个async useEffect

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.) (请注意,您有责任处理由于组件在 promise 解析之前被销毁而引起的任何竞争条件,尽管在已销毁的组件内分配 state 是无害的。)

I've opened an issue to discuss providing more useful feedback in these situations: https://github.com/sveltejs/svelte/issues/4944我已经打开一个问题来讨论在这些情况下提供更有用的反馈: https://github.com/sveltejs/svelte/issues/4944

onMount must be synchronous. onMount必须是同步的。 However, you can use an {#await} block in your markup and make lazyLoading async , for example:但是,您可以在标记中使用{#await}并使lazyLoading async ,例如:

{#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:这样做的额外好处是允许您使用加载程序以及在 promise 被拒绝时出现的标记,使用以下语法:

{#await promise}
  loading
{:then value}
  loaded {value}
{:catch error}
  failed with {error}
{/await}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM