diff --git a/.changeset/brave-owls-wait.md b/.changeset/brave-owls-wait.md new file mode 100644 index 0000000000..827868b8c3 --- /dev/null +++ b/.changeset/brave-owls-wait.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't create async deriveds for a component destroyed while waiting for its top-level `await` diff --git a/packages/svelte/src/internal/client/reactivity/async.js b/packages/svelte/src/internal/client/reactivity/async.js index a75f97a54f..efdfe6625c 100644 --- a/packages/svelte/src/internal/client/reactivity/async.js +++ b/packages/svelte/src/internal/client/reactivity/async.js @@ -103,6 +103,11 @@ export function flatten(blockers, sync, async, fn) { if (blocker_promise) { blocker_promise.then(() => { + if ((parent.f & DESTROYED) !== 0) { + decrement_pending(); + return; + } + restore(); run(); unset_context(); diff --git a/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/Child.svelte new file mode 100644 index 0000000000..63a16dde43 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/Child.svelte @@ -0,0 +1,7 @@ + + +
{await Promise.resolve(value)}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/_config.js b/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/_config.js new file mode 100644 index 0000000000..096f90e2df --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/_config.js @@ -0,0 +1,31 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const [hide, resolve] = target.querySelectorAll('button'); + + assert.htmlEqual( + target.innerHTML, + ` + + +loading...
+ ` + ); + + hide.click(); + await tick(); + + resolve.click(); + await tick(); + + assert.htmlEqual( + target.innerHTML, + ` + + + ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/main.svelte new file mode 100644 index 0000000000..3bc50e5d24 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-destroyed-before-blockers-settle/main.svelte @@ -0,0 +1,20 @@ + + + + + +loading...
+ {/snippet} +