mirror of https://github.com/sveltejs/svelte
parent
1ce167a7cb
commit
072b97d426
@ -0,0 +1,36 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
const buttons = '<button>b</button><button>z</button><button>shift</button>';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target, logs }) {
|
||||
await tick();
|
||||
const [b, z, shift] = target.querySelectorAll('button');
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `<p>0</p><p>a</p>${buttons}`);
|
||||
assert.deepEqual(logs, ['fetch a']);
|
||||
|
||||
// write x = 'b' — the batch is pending on its async expression
|
||||
b.click();
|
||||
await tick();
|
||||
assert.deepEqual(logs, ['fetch a', 'fetch b']);
|
||||
|
||||
// an independent batch runs the effect, which writes x = 'b' — the
|
||||
// real value is already 'b', so this is a no-op: the async expression
|
||||
// must not re-run (no needless refetch), and the batch must not be
|
||||
// entangled with the pending one (z commits immediately)
|
||||
z.click();
|
||||
await tick();
|
||||
assert.deepEqual(logs, ['fetch a', 'fetch b']);
|
||||
assert.htmlEqual(target.innerHTML, `<p>1</p><p>a</p>${buttons}`);
|
||||
|
||||
// the pending batch settles
|
||||
shift.click();
|
||||
await tick();
|
||||
shift.click();
|
||||
await tick();
|
||||
assert.deepEqual(logs, ['fetch a', 'fetch b']);
|
||||
assert.htmlEqual(target.innerHTML, `<p>1</p><p>b</p>${buttons}`);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,25 @@
|
||||
<script>
|
||||
let x = $state('a');
|
||||
let z = $state(0);
|
||||
let pend = false;
|
||||
|
||||
const deferred = [];
|
||||
|
||||
function delay(value) {
|
||||
console.log(`fetch ${value}`);
|
||||
if (!pend) return value;
|
||||
return new Promise((resolve) => deferred.push(() => resolve(value)));
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if (z > 0) {
|
||||
x = 'b';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>{z}</p>
|
||||
<p>{await delay(x)}</p>
|
||||
<button onclick={() => { pend = true; x = 'b'; }}>b</button>
|
||||
<button onclick={() => z++}>z</button>
|
||||
<button onclick={() => deferred.shift()?.()}>shift</button>
|
||||
@ -0,0 +1,33 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
const buttons = '<button>b</button><button>reset</button><button>shift</button>';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target, logs }) {
|
||||
await tick();
|
||||
const [b, reset, shift] = target.querySelectorAll('button');
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `<p>0</p><p>a</p>${buttons}`);
|
||||
assert.deepEqual(logs, ['fetch a']);
|
||||
|
||||
// write x = 'b' — the batch is pending on its async expression
|
||||
b.click();
|
||||
await tick();
|
||||
assert.deepEqual(logs, ['fetch a', 'fetch b']);
|
||||
|
||||
// an independent batch runs the effect, which resets x = 'a'. The real
|
||||
// (pending) value is 'b', so this is a genuine change and must not be
|
||||
// swallowed just because the effect's world still shows 'a'
|
||||
reset.click();
|
||||
await tick();
|
||||
assert.deepEqual(logs, ['fetch a', 'fetch b', 'fetch a']);
|
||||
|
||||
// resolve all in-flight runs — the reset must win
|
||||
shift.click();
|
||||
await tick();
|
||||
shift.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `<p>1</p><p>a</p>${buttons}`);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,25 @@
|
||||
<script>
|
||||
let x = $state('a');
|
||||
let z = $state(0);
|
||||
let pend = false;
|
||||
|
||||
const deferred = [];
|
||||
|
||||
function delay(value) {
|
||||
console.log(`fetch ${value}`);
|
||||
if (!pend) return value;
|
||||
return new Promise((resolve) => deferred.push(() => resolve(value)));
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if (z > 0) {
|
||||
x = 'a';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>{z}</p>
|
||||
<p>{await delay(x)}</p>
|
||||
<button onclick={() => { pend = true; x = 'b'; }}>b</button>
|
||||
<button onclick={() => z++}>reset</button>
|
||||
<button onclick={() => deferred.shift()?.()}>shift</button>
|
||||
Loading…
Reference in new issue