diff --git a/.changeset/metal-parents-train.md b/.changeset/metal-parents-train.md new file mode 100644 index 000000000000..57c99453c339 --- /dev/null +++ b/.changeset/metal-parents-train.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: flush batches whenever an async value resolves diff --git a/packages/svelte/src/internal/client/reactivity/async.js b/packages/svelte/src/internal/client/reactivity/async.js index 4d572281b76a..45c78ff926b9 100644 --- a/packages/svelte/src/internal/client/reactivity/async.js +++ b/packages/svelte/src/internal/client/reactivity/async.js @@ -52,8 +52,6 @@ export function flatten(sync, async, fn) { Promise.all(async.map((expression) => async_derived(expression))) .then((result) => { - batch?.activate(); - restore(); try { diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index fb704edb1325..102d0670b664 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -178,6 +178,8 @@ export class Batch { flush_queued_effects(render_effects); flush_queued_effects(effects); + previous_batch = null; + this.#deferred?.resolve(); } else { this.#defer_effects(this.#render_effects); @@ -280,17 +282,6 @@ export class Batch { deactivate() { current_batch = null; - previous_batch = null; - - for (const update of effect_pending_updates) { - effect_pending_updates.delete(update); - update(); - - if (current_batch !== null) { - // only do one at a time - break; - } - } } flush() { @@ -307,6 +298,16 @@ export class Batch { } this.deactivate(); + + for (const update of effect_pending_updates) { + effect_pending_updates.delete(update); + update(); + + if (current_batch !== null) { + // only do one at a time + break; + } + } } /** @@ -375,21 +376,17 @@ export class Batch { decrement() { this.#pending -= 1; - if (this.#pending === 0) { - for (const e of this.#dirty_effects) { - set_signal_status(e, DIRTY); - schedule_effect(e); - } - - for (const e of this.#maybe_dirty_effects) { - set_signal_status(e, MAYBE_DIRTY); - schedule_effect(e); - } + for (const e of this.#dirty_effects) { + set_signal_status(e, DIRTY); + schedule_effect(e); + } - this.flush(); - } else { - this.deactivate(); + for (const e of this.#maybe_dirty_effects) { + set_signal_status(e, MAYBE_DIRTY); + schedule_effect(e); } + + this.flush(); } /** @param {() => void} fn */