mirror of https://github.com/vuejs/core.git
fix(reactivity): fix nested batch edge case
This commit is contained in:
parent
aa9ef2386a
commit
93c95dd4cd
|
@ -229,4 +229,35 @@ describe('watch', () => {
|
||||||
expect(r.value).toBe(1)
|
expect(r.value).toBe(1)
|
||||||
expect(c.value).toBe(1)
|
expect(c.value).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// edge case where a nested endBatch() causes an effect to be batched in a
|
||||||
|
// nested batch loop with its .next mutated, causing the outer loop to end
|
||||||
|
// early
|
||||||
|
test('nested batch edge case', () => {
|
||||||
|
// useClamp from VueUse
|
||||||
|
const clamp = (n: number, min: number, max: number) =>
|
||||||
|
Math.min(max, Math.max(min, n))
|
||||||
|
function useClamp(src: Ref<number>, min: number, max: number) {
|
||||||
|
return computed({
|
||||||
|
get() {
|
||||||
|
return (src.value = clamp(src.value, min, max))
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
src.value = clamp(val, min, max)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const src = ref(1)
|
||||||
|
const clamped = useClamp(src, 1, 5)
|
||||||
|
watch(src, val => (clamped.value = val))
|
||||||
|
|
||||||
|
const spy = vi.fn()
|
||||||
|
watch(clamped, spy)
|
||||||
|
|
||||||
|
src.value = 2
|
||||||
|
expect(spy).toHaveBeenCalledTimes(1)
|
||||||
|
src.value = 10
|
||||||
|
expect(spy).toHaveBeenCalledTimes(2)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -274,6 +274,8 @@ export function endBatch(): void {
|
||||||
batchedSub = undefined
|
batchedSub = undefined
|
||||||
// 2nd pass: run effects
|
// 2nd pass: run effects
|
||||||
while (e) {
|
while (e) {
|
||||||
|
next = e.next
|
||||||
|
e.next = undefined
|
||||||
e.flags &= ~EffectFlags.NOTIFIED
|
e.flags &= ~EffectFlags.NOTIFIED
|
||||||
if (e.flags & EffectFlags.ACTIVE) {
|
if (e.flags & EffectFlags.ACTIVE) {
|
||||||
try {
|
try {
|
||||||
|
@ -283,8 +285,6 @@ export function endBatch(): void {
|
||||||
if (!error) error = err
|
if (!error) error = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next = e.next
|
|
||||||
e.next = undefined
|
|
||||||
e = next
|
e = next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue