mirror of https://github.com/sveltejs/svelte
parent
b1cadd1eae
commit
721dc71249
@ -0,0 +1,41 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
const buttons = '<button>a</button> <button>b</button> <button>shift</button> <button>pop</button>';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
await tick();
|
||||
|
||||
const [a, b, , pop] = target.querySelectorAll('button');
|
||||
const shift = target.querySelectorAll('button')[2];
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `${buttons} <p>a</p><p>a</p><p>aa</p><p>1</p>`);
|
||||
|
||||
// start two independent batches, both blocked on their awaited expression
|
||||
a.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `${buttons} <p>a</p><p>a</p><p>aa</p><p>1</p>`);
|
||||
|
||||
b.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `${buttons} <p>a</p><p>a</p><p>aa</p><p>1</p>`);
|
||||
|
||||
// resolve the newer (b) batch first. Committing it must not commit the
|
||||
// still-pending `a` batch, whose async work has not completed — `a` must
|
||||
// still read 'a', and the unrelated `c` update must not be blocked
|
||||
pop.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `${buttons} <p>a</p><p>b</p><p>ab</p><p>2</p>`);
|
||||
|
||||
// stale promise from the `a` batch's first run — resolving it does nothing
|
||||
shift.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `${buttons} <p>a</p><p>b</p><p>ab</p><p>2</p>`);
|
||||
|
||||
// the `a` batch's re-run await ('bb') resolves — everything is committed
|
||||
shift.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `${buttons} <p>b</p><p>b</p><p>bb</p><p>2</p>`);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,38 @@
|
||||
<script>
|
||||
let a = $state('a');
|
||||
let b = $state('a');
|
||||
let c = $state(0);
|
||||
|
||||
let n = 0;
|
||||
|
||||
let queued = [];
|
||||
let first = true;
|
||||
|
||||
function push(v) {
|
||||
if (first) {
|
||||
first = false;
|
||||
return v;
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
queued.push(() => resolve(v));
|
||||
});
|
||||
}
|
||||
|
||||
// when a batch changing `b` commits, this writes `c` during that batch's
|
||||
// flush phase — the write lands in a freshly-created batch
|
||||
$effect(() => {
|
||||
b;
|
||||
c = ++n;
|
||||
});
|
||||
</script>
|
||||
|
||||
<button onclick={() => a = 'b'}>a</button>
|
||||
<button onclick={() => b = 'b'}>b</button>
|
||||
<button onclick={() => queued.shift()?.()}>shift</button>
|
||||
<button onclick={() => queued.pop()?.()}>pop</button>
|
||||
|
||||
<p>{a}</p>
|
||||
<p>{b}</p>
|
||||
<p>{await push(a + b)}</p>
|
||||
<p>{c}</p>
|
||||
Loading…
Reference in new issue