fix(watch): flush:pre watchers should not fire if state change causes

owner component to unmount

fix #2291
This commit is contained in:
Evan You
2022-08-15 19:00:55 +08:00
parent a95554d35c
commit 78c199d6db
5 changed files with 68 additions and 142 deletions

View File

@@ -3,9 +3,8 @@ import {
nextTick,
queuePostFlushCb,
invalidateJob,
queuePreFlushCb,
flushPreFlushCbs,
flushPostFlushCbs
flushPostFlushCbs,
flushPreFlushCbs
} from '../src/scheduler'
describe('scheduler', () => {
@@ -114,65 +113,7 @@ describe('scheduler', () => {
})
})
describe('queuePreFlushCb', () => {
it('basic usage', async () => {
const calls: string[] = []
const cb1 = () => {
calls.push('cb1')
}
const cb2 = () => {
calls.push('cb2')
}
queuePreFlushCb(cb1)
queuePreFlushCb(cb2)
expect(calls).toEqual([])
await nextTick()
expect(calls).toEqual(['cb1', 'cb2'])
})
it('should dedupe queued preFlushCb', async () => {
const calls: string[] = []
const cb1 = () => {
calls.push('cb1')
}
const cb2 = () => {
calls.push('cb2')
}
const cb3 = () => {
calls.push('cb3')
}
queuePreFlushCb(cb1)
queuePreFlushCb(cb2)
queuePreFlushCb(cb1)
queuePreFlushCb(cb2)
queuePreFlushCb(cb3)
expect(calls).toEqual([])
await nextTick()
expect(calls).toEqual(['cb1', 'cb2', 'cb3'])
})
it('chained queuePreFlushCb', async () => {
const calls: string[] = []
const cb1 = () => {
calls.push('cb1')
// cb2 will be executed after cb1 at the same tick
queuePreFlushCb(cb2)
}
const cb2 = () => {
calls.push('cb2')
}
queuePreFlushCb(cb1)
await nextTick()
expect(calls).toEqual(['cb1', 'cb2'])
})
})
describe('queueJob w/ queuePreFlushCb', () => {
describe('pre flush jobs', () => {
it('queueJob inside preFlushCb', async () => {
const calls: string[] = []
const job1 = () => {
@@ -183,8 +124,9 @@ describe('scheduler', () => {
calls.push('cb1')
queueJob(job1)
}
cb1.pre = true
queuePreFlushCb(cb1)
queueJob(cb1)
await nextTick()
expect(calls).toEqual(['cb1', 'job1'])
})
@@ -194,17 +136,23 @@ describe('scheduler', () => {
const job1 = () => {
calls.push('job1')
}
job1.id = 1
const cb1 = () => {
calls.push('cb1')
queueJob(job1)
// cb2 should execute before the job
queuePreFlushCb(cb2)
queueJob(cb2)
}
cb1.pre = true
const cb2 = () => {
calls.push('cb2')
}
cb2.pre = true
cb2.id = 1
queuePreFlushCb(cb1)
queueJob(cb1)
await nextTick()
expect(calls).toEqual(['cb1', 'cb2', 'job1'])
})
@@ -216,9 +164,9 @@ describe('scheduler', () => {
// when updating the props of a child component. This is handled
// directly inside `updateComponentPreRender` to avoid non atomic
// cb triggers (#1763)
queuePreFlushCb(cb1)
queuePreFlushCb(cb2)
flushPreFlushCbs(undefined, job1)
queueJob(cb1)
queueJob(cb2)
flushPreFlushCbs()
calls.push('job1')
}
const cb1 = () => {
@@ -226,9 +174,11 @@ describe('scheduler', () => {
// a cb triggers its parent job, which should be skipped
queueJob(job1)
}
cb1.pre = true
const cb2 = () => {
calls.push('cb2')
}
cb2.pre = true
queueJob(job1)
await nextTick()
@@ -237,12 +187,14 @@ describe('scheduler', () => {
// #3806
it('queue preFlushCb inside postFlushCb', async () => {
const cb = jest.fn()
const spy = jest.fn()
const cb = () => spy()
cb.pre = true
queuePostFlushCb(() => {
queuePreFlushCb(cb)
queueJob(cb)
})
await nextTick()
expect(cb).toHaveBeenCalled()
expect(spy).toHaveBeenCalled()
})
})