mirror of https://github.com/sveltejs/svelte
The committing batch needs the correct previous value, and the new batch must record that its value came from the committing batch's world.async-another-try-pt-1-prune
parent
498a696ac8
commit
70bb7f4295
@ -0,0 +1,33 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
// Batch B (x) commits while an earlier batch A (y) is still pending, but B stays around because
|
||||
// of the async work in the new boundary. While B flushes its effects, an effect creates a new batch C,
|
||||
// and `d` is computed for the first time afterwards (so it's captured in both B and C). When A
|
||||
// commits later, it sees B's previous values, which must be consistent (`d` must be `x * 2`).
|
||||
export default test({
|
||||
async test({ assert, target, logs }) {
|
||||
await tick();
|
||||
const [y, x, shift] = target.querySelectorAll('button');
|
||||
assert.deepEqual(logs, [0, 0, 0]);
|
||||
|
||||
// A
|
||||
y.click();
|
||||
await tick();
|
||||
|
||||
// B
|
||||
x.click();
|
||||
await tick();
|
||||
assert.deepEqual(logs, [0, 0, 0, 0, 1, 2]);
|
||||
|
||||
// A commits
|
||||
shift.click();
|
||||
await tick();
|
||||
|
||||
for (let i = 0; i < logs.length; i += 3) {
|
||||
assert.equal(logs[i + 2], logs[i + 1] * 2, `torn read: ${logs.slice(i, i + 3)}`);
|
||||
}
|
||||
|
||||
assert.deepEqual(logs.slice(-3), [1, 1, 2]);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,38 @@
|
||||
<script>
|
||||
import { untrack } from 'svelte';
|
||||
|
||||
let x = $state(0);
|
||||
let y = $state(0);
|
||||
let z = $state(0);
|
||||
let d = $derived(x * 2);
|
||||
|
||||
const queue = [];
|
||||
function push(v) {
|
||||
return new Promise((r) => queue.push(() => r(v)));
|
||||
}
|
||||
|
||||
// creates a new batch while the batch that changed `x` flushes its effects...
|
||||
$effect(() => {
|
||||
if (x) untrack(() => z++);
|
||||
});
|
||||
|
||||
// ...before `d` is computed for the first time in that batch
|
||||
$effect(() => {
|
||||
console.log(y, x, d);
|
||||
});
|
||||
</script>
|
||||
|
||||
<button onclick={() => y++}>y</button>
|
||||
<button onclick={() => x++}>x</button>
|
||||
<button onclick={() => queue.shift()()}>shift</button>
|
||||
|
||||
<p>{y ? await push(y) : y}</p>
|
||||
|
||||
{#if x}
|
||||
<svelte:boundary>
|
||||
<p>{await push(x)}</p>
|
||||
{#snippet pending()}
|
||||
<p>loading</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
||||
{/if}
|
||||
Loading…
Reference in new issue