mirror of https://github.com/sveltejs/svelte
fix: ensure async deriveds always get dependencies from thennable (#16672)
When an async derived already has a previous promise that is still pending, we were not accessing the `then` property of the new promise. If that property access causes signals to be read, that meant that those dependencies were lost and as such the derived wouldn't rerun anymore when it should. The fix is to make sure to always access the thennable.pull/16673/head
parent
967431c1a7
commit
677af5723c
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: ensure async deriveds always get dependencies from thennable
|
@ -0,0 +1,41 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const [increment, pop] = target.querySelectorAll('button');
|
||||
|
||||
increment.click();
|
||||
await tick();
|
||||
|
||||
pop.click();
|
||||
await tick();
|
||||
|
||||
pop.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>increment</button>
|
||||
<button>pop</button>
|
||||
<p>1</p>
|
||||
`
|
||||
);
|
||||
|
||||
increment.click();
|
||||
await tick();
|
||||
|
||||
pop.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>increment</button>
|
||||
<button>pop</button>
|
||||
<p>2</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
});
|
@ -0,0 +1,35 @@
|
||||
|
||||
<script>
|
||||
let count = $state(0);
|
||||
|
||||
let deferreds = [];
|
||||
|
||||
class X {
|
||||
constructor(promise) {
|
||||
this.promise = promise;
|
||||
}
|
||||
|
||||
get then() {
|
||||
count;
|
||||
|
||||
return (resolve) => this.promise.then(() => count).then(resolve)
|
||||
}
|
||||
}
|
||||
|
||||
function push() {
|
||||
const deferred = Promise.withResolvers();
|
||||
deferreds.push(deferred);
|
||||
return new X(deferred.promise);
|
||||
}
|
||||
</script>
|
||||
|
||||
<button onclick={() => count += 1}>increment</button>
|
||||
<button onclick={() => deferreds.pop()?.resolve(count)}>pop</button>
|
||||
|
||||
<svelte:boundary>
|
||||
<p>{await push()}</p>
|
||||
|
||||
{#snippet pending()}
|
||||
<p>loading...</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
Loading…
Reference in new issue