mirror of https://github.com/sveltejs/svelte
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/16672/head
parent
0d48916e02
commit
5d3db10239
@ -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