mirror of https://github.com/sveltejs/svelte
tweak equality comparisons; keep dependencies not only for forks, and not only reactions but also deps
parent
61f58a5566
commit
d654c969d3
@ -0,0 +1,40 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
const buttons =
|
||||||
|
'<button>b = 1</button><button>b = 2, c = 1</button><button>resolve latest pos</button><button>resolve oldest pos</button><button>resolve all</button>';
|
||||||
|
|
||||||
|
// Like `async-equal-result-dropped-later-batch`, but the result is read by something that doesn't wait
|
||||||
|
// for it: a batch's async result equals the real value, which a later (still pending) batch wrote. The
|
||||||
|
// batch itself sees that later batch's previous value though, so the result changes its world, and
|
||||||
|
// whatever read the previous value has to update
|
||||||
|
export default test({
|
||||||
|
mode: ['client'],
|
||||||
|
async test({ assert, target }) {
|
||||||
|
await tick();
|
||||||
|
const [b1, b2c1, resolve_latest, resolve_oldest, resolve_all] =
|
||||||
|
target.querySelectorAll('button');
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `${buttons}<p>zero</p><span>0</span><i>c0</i>`);
|
||||||
|
|
||||||
|
b1.click();
|
||||||
|
await tick();
|
||||||
|
b2c1.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `${buttons}<p>zero</p><span>0</span><i>c0</i>`);
|
||||||
|
|
||||||
|
// the later batch's result becomes the real value, but that batch still waits for c1
|
||||||
|
resolve_latest.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `${buttons}<p>zero</p><span>0</span><i>c0</i>`);
|
||||||
|
|
||||||
|
// the earlier batch's equal result completes it
|
||||||
|
resolve_oldest.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `${buttons}<p>pos</p><span>1</span><i>c0</i>`);
|
||||||
|
|
||||||
|
resolve_all.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `${buttons}<p>pos</p><span>2</span><i>c1</i>`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
<script>
|
||||||
|
let b = $state(0);
|
||||||
|
let c = $state(0);
|
||||||
|
|
||||||
|
/** @type {Map<string, Array<() => void>>} */
|
||||||
|
const pending = new Map();
|
||||||
|
let initial = true;
|
||||||
|
|
||||||
|
/** @param {string} value */
|
||||||
|
function f(value) {
|
||||||
|
if (initial) return value;
|
||||||
|
return new Promise((fulfil) => {
|
||||||
|
if (!pending.has(value)) pending.set(value, []);
|
||||||
|
pending.get(value)?.push(() => fulfil(value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
initial = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
function resolve_all() {
|
||||||
|
for (const list of pending.values()) {
|
||||||
|
for (const fn of list.splice(0)) fn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = $derived(await f(b > 0 ? 'pos' : 'zero'));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => (b = 1)}>b = 1</button>
|
||||||
|
<button onclick={() => ((b = 2), (c = 1))}>b = 2, c = 1</button>
|
||||||
|
<button onclick={() => pending.get('pos')?.pop()?.()}>resolve latest pos</button>
|
||||||
|
<button onclick={() => pending.get('pos')?.shift()?.()}>resolve oldest pos</button>
|
||||||
|
<button onclick={resolve_all}>resolve all</button>
|
||||||
|
|
||||||
|
<p>{p}</p>
|
||||||
|
{#if true}<span>{b}</span>{/if}
|
||||||
|
<i>{await f('c' + c)}</i>
|
||||||
Loading…
Reference in new issue