mirror of https://github.com/sveltejs/svelte
fix: propagate async @const blockers through closure references (#18309)
Right now, if you have the following:
```svelte
{@const data = await foo}
<p>{(() => data)()}<p>
```
It will blow up during CSR, because it tries to read `data` before it
exists. The solution to this is to consider references inside closures
as blockers for those closures. This _does_ mean we'll overblock in some
circumstances, such as:
```svelte
{@const data = await foo}
<button onclick={() => data}>foo<button>
```
But I wonder if that's actually incorrect? If the user were to click
`onclick` before `data` is ready, it would blow up.
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/18311/head
parent
ec08dbc7ee
commit
e705369dee
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: propagate async `@const` blockers through closure references so template expressions like `{(() => host)()}` correctly wait for the awaited value
|
||||
@ -0,0 +1,14 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
// Tests that an IIFE referencing an `await` @const inside an {#each} block
|
||||
// correctly registers the async dependency so the template waits for the
|
||||
// resolved value instead of rendering with `undefined`.
|
||||
export default test({
|
||||
mode: ['client', 'hydrate', 'async-server'],
|
||||
ssrHtml: '<p>example.com</p>',
|
||||
async test({ assert, target }) {
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, '<p>example.com</p>');
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
<script>
|
||||
async function get_host() {
|
||||
return 'example.com';
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each { length: 1 } as nothing}
|
||||
{@const host = await get_host()}
|
||||
<p>{(() => host)()}</p>
|
||||
{/each}
|
||||
Loading…
Reference in new issue