fix(runtime-core/scheduler): only allow watch callbacks to be self-triggering

fix #1740

Previous fix for #1727 caused `watchEffect` to also recursively trigger
itself on reactive array mutations which implicitly registers array
`.length` as dependencies and mutates it at the same time.

This fix limits recursive trigger behavior to only `watch()` callbacks
since code inside the callback do not register dependencies and
mutations are always explicitly intended.
This commit is contained in:
Evan You
2020-07-30 17:54:05 -04:00
parent ccf3362d4d
commit 09702e95b9
3 changed files with 108 additions and 31 deletions

View File

@@ -308,5 +308,49 @@ describe('scheduler', () => {
expect(
`Unhandled error during execution of scheduler flush`
).toHaveBeenWarned()
// this one should no longer error
await nextTick()
})
test('should prevent self-triggering jobs by default', async () => {
let count = 0
const job = () => {
if (count < 3) {
count++
queueJob(job)
}
}
queueJob(job)
await nextTick()
// only runs once - a job cannot queue itself
expect(count).toBe(1)
})
test('should allow watcher callbacks to trigger itself', async () => {
// normal job
let count = 0
const job = () => {
if (count < 3) {
count++
queueJob(job)
}
}
job.cb = true
queueJob(job)
await nextTick()
expect(count).toBe(3)
// post cb
const cb = () => {
if (count < 5) {
count++
queuePostFlushCb(cb)
}
}
cb.cb = true
queuePostFlushCb(cb)
await nextTick()
expect(count).toBe(5)
})
})