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