Skip to content

Commit 10ff159

Browse files
committedSep 26, 2024··
fix(reactivity): fix recursive sync watcher on computed edge case
close #12033 close #12037
1 parent cb34b28 commit 10ff159

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed
 

‎packages/reactivity/__tests__/watch.spec.ts

+20
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
WatchErrorCodes,
55
type WatchOptions,
66
type WatchScheduler,
7+
computed,
78
onWatcherCleanup,
89
ref,
910
watch,
@@ -209,4 +210,23 @@ describe('watch', () => {
209210
source.value++
210211
expect(dummy).toBe(1)
211212
})
213+
214+
// #12033
215+
test('recursive sync watcher on computed', () => {
216+
const r = ref(0)
217+
const c = computed(() => r.value)
218+
219+
watch(c, v => {
220+
if (v > 1) {
221+
r.value--
222+
}
223+
})
224+
225+
expect(r.value).toBe(0)
226+
expect(c.value).toBe(0)
227+
228+
r.value = 10
229+
expect(r.value).toBe(1)
230+
expect(c.value).toBe(1)
231+
})
212232
})

‎packages/reactivity/src/effect.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,14 @@ export function endBatch(): void {
260260
let error: unknown
261261
while (batchedSub) {
262262
let e: Subscriber | undefined = batchedSub
263-
batchedSub = undefined
263+
let next: Subscriber | undefined
264264
while (e) {
265-
const next: Subscriber | undefined = e.next
266-
e.next = undefined
267265
e.flags &= ~EffectFlags.NOTIFIED
266+
e = e.next
267+
}
268+
e = batchedSub
269+
batchedSub = undefined
270+
while (e) {
268271
if (e.flags & EffectFlags.ACTIVE) {
269272
try {
270273
// ACTIVE flag is effect-only
@@ -273,6 +276,8 @@ export function endBatch(): void {
273276
if (!error) error = err
274277
}
275278
}
279+
next = e.next
280+
e.next = undefined
276281
e = next
277282
}
278283
}

0 commit comments

Comments
 (0)
Please sign in to comment.