From 1dd383ea5416551ac0314d35ef58254f28232bb0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 3 May 2025 18:48:46 +0200 Subject: [PATCH] enforce linear order --- .../internal/client/reactivity/deriveds.js | 19 ++++++++++++++++++- .../_config.js | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 5c33a827dd..c508e515c0 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -106,14 +106,27 @@ export function async_derived(fn, location) { var promise = /** @type {Promise} */ (/** @type {unknown} */ (undefined)); var signal = source(/** @type {V} */ (UNINITIALIZED)); + /** @type {Promise | null} */ + var prev = null; + // only suspend in async deriveds created on initialisation var should_suspend = !active_reaction; render_effect(() => { if (DEV) from_async_derived = active_effect; - promise = Promise.resolve(fn()); + var p = fn(); if (DEV) from_async_derived = null; + promise = + prev === null + ? Promise.resolve(p) + : prev.then( + () => p, + () => p + ); + + prev = promise; + var restore = capture(); var batch = /** @type {Batch} */ (current_batch); @@ -129,6 +142,8 @@ export function async_derived(fn, location) { promise.then( (v) => { + prev = null; + if ((parent.f & DESTROYED) !== 0) { return; } @@ -160,6 +175,8 @@ export function async_derived(fn, location) { } }, (e) => { + prev = null; + handle_error(e, parent, null, parent.ctx); } ); diff --git a/packages/svelte/tests/runtime-runes/samples/async-derived-invalidation-during-init/_config.js b/packages/svelte/tests/runtime-runes/samples/async-derived-invalidation-during-init/_config.js index c8f20d9597..99f91503e1 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-derived-invalidation-during-init/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/async-derived-invalidation-during-init/_config.js @@ -34,6 +34,7 @@ export default test({ await Promise.resolve(); await Promise.resolve(); await Promise.resolve(); + await Promise.resolve(); await tick(); assert.htmlEqual(target.innerHTML, '

hello

');