diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index f341252ffc..e73618c026 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -160,61 +160,23 @@ export class Batch { this.#process_root(root); } + // if we didn't start any new async work, and no async work + // is outstanding from a previous flush, commit if (this.#async_effects.length === 0 && this.#pending === 0) { - var merged = false; + var render_effects = this.#render_effects; + var effects = this.#effects; - // if there are older batches with overlapping - // state, we can't commit this batch. instead, - // we merge it into the older batches - for (const batch of batches) { - if (batch === this) break; - - for (const [source] of batch.#current) { - if (this.#current.has(source)) { - merged = true; - - for (const [source, value] of this.#current) { - batch.#current.set(source, value); - } - - for (const e of this.#render_effects) { - set_signal_status(e, CLEAN); - batch.#render_effects.push(e); - } - - for (const e of this.#effects) { - set_signal_status(e, CLEAN); - batch.#effects.push(e); - } - - for (const e of this.skipped_effects) { - batch.skipped_effects.add(e); - } - - for (const fn of this.#callbacks) { - batch.#callbacks.add(fn); - } - - break; - } - } - } - - if (!merged) { - var render_effects = this.#render_effects; - var effects = this.#effects; - - this.#render_effects = []; - this.#effects = []; + this.#render_effects = []; + this.#effects = []; - this.#commit(); + this.#commit(); - flush_queued_effects(render_effects); - flush_queued_effects(effects); + flush_queued_effects(render_effects); + flush_queued_effects(effects); - this.#deferred?.resolve(); - } + this.#deferred?.resolve(); } else { + // otherwise mark effects clean so they get scheduled on the next run for (const e of this.#render_effects) set_signal_status(e, CLEAN); for (const e of this.#effects) set_signal_status(e, CLEAN); } diff --git a/packages/svelte/tests/runtime-runes/samples/async-unresolved-promise/_config.js b/packages/svelte/tests/runtime-runes/samples/async-unresolved-promise/_config.js new file mode 100644 index 0000000000..e9ccbba2b6 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-unresolved-promise/_config.js @@ -0,0 +1,32 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + await tick(); + + const [increment] = target.querySelectorAll('button'); + + assert.htmlEqual( + target.innerHTML, + ` + +
0
+ ` + ); + + increment.click(); + await tick(); + + increment.click(); + await tick(); + + assert.htmlEqual( + target.innerHTML, + ` + +2
+ ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-unresolved-promise/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-unresolved-promise/main.svelte new file mode 100644 index 0000000000..e0619a1fe4 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-unresolved-promise/main.svelte @@ -0,0 +1,19 @@ + + + + +{await new Promise(() => {})}
+ {:else} +{await count}
+ {/if} + + {#snippet pending()} +loading...
+ {/snippet} +