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