Skip to content

Commit 0dc84ab

Browse files
committed
only suspend in top-level async deriveds
1 parent 80b713a commit 0dc84ab

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

packages/svelte/src/internal/client/reactivity/deriveds.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { get_stack } from '../dev/tracing.js';
2929
import { tracing_mode_flag } from '../../flags/index.js';
3030
import { capture, suspend } from '../dom/blocks/boundary.js';
3131
import { component_context } from '../context.js';
32+
import { noop } from '../../shared/utils.js';
3233

3334
/** @type {Effect | null} */
3435
export let from_async_derived = null;
@@ -100,14 +101,17 @@ export function async_derived(fn, detect_waterfall = true) {
100101
var promise = /** @type {Promise<V>} */ (/** @type {unknown} */ (undefined));
101102
var value = source(/** @type {V} */ (undefined));
102103

104+
// only suspend in async deriveds created on initialisation
105+
var should_suspend = !active_reaction;
106+
103107
// TODO this isn't a block
104108
block(async () => {
105109
if (DEV) from_async_derived = active_effect;
106110
var current = (promise = fn());
107111
if (DEV) from_async_derived = null;
108112

109113
var restore = capture();
110-
var unsuspend = suspend();
114+
var unsuspend = should_suspend ? suspend() : noop;
111115

112116
try {
113117
var v = await promise;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script>
2+
let { count } = $props();
3+
4+
async function x() {
5+
let d = $derived(await new Promise((f) => {}));
6+
}
7+
8+
let indirect = $derived(x() && count);
9+
</script>
10+
11+
<p>{indirect}</p>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { flushSync, tick } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target }) {
6+
await tick();
7+
assert.htmlEqual(target.innerHTML, '<button>0</button><p>0</p>');
8+
9+
const button = target.querySelector('button');
10+
11+
flushSync(() => button?.click());
12+
assert.htmlEqual(target.innerHTML, '<button>1</button><p>1</p>');
13+
}
14+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
import Child from './Child.svelte';
3+
4+
let count = $state(0);
5+
</script>
6+
7+
<button onclick={() => count += 1}>{count}</button>
8+
9+
<svelte:boundary>
10+
<Child {count} />
11+
12+
{#snippet pending()}
13+
<p>pending</p>
14+
{/snippet}
15+
</svelte:boundary>
16+
17+
{console.log(`outside boundary ${count}`)}

0 commit comments

Comments
 (0)