diff --git a/packages/runtime-core/__tests__/scheduler.spec.ts b/packages/runtime-core/__tests__/scheduler.spec.ts index 781aa6eb0b7..1805096692a 100644 --- a/packages/runtime-core/__tests__/scheduler.spec.ts +++ b/packages/runtime-core/__tests__/scheduler.spec.ts @@ -411,31 +411,59 @@ describe('scheduler', () => { }) }) - test('invalidateJob', async () => { - const calls: string[] = [] - const job1 = () => { - calls.push('job1') - invalidateJob(job2) - job2() - } - const job2 = () => { - calls.push('job2') - } - const job3 = () => { - calls.push('job3') - } - const job4 = () => { - calls.push('job4') - } - // queue all jobs - queueJob(job1) - queueJob(job2) - queueJob(job3) - queuePostFlushCb(job4) - expect(calls).toEqual([]) - await nextTick() - // job2 should be called only once - expect(calls).toEqual(['job1', 'job2', 'job3', 'job4']) + describe('invalidateJob', () => { + test('invalidateJob', async () => { + const calls: string[] = [] + const job1 = () => { + calls.push('job1') + invalidateJob(job2) + job2() + } + const job2 = () => { + calls.push('job2') + } + const job3 = () => { + calls.push('job3') + } + const job4 = () => { + calls.push('job4') + } + // queue all jobs + queueJob(job1) + queueJob(job2) + queueJob(job3) + queuePostFlushCb(job4) + expect(calls).toEqual([]) + await nextTick() + // job2 should be called only once + expect(calls).toEqual(['job1', 'job2', 'job3', 'job4']) + }) + + test('correct job is invalidated when a job is duplicated', async () => { + const calls: string[] = [] + let first = true + const job1 = () => { + calls.push('job1') + // We only trigger the child the first time we 'render' + if (first) { + first = false + queueJob(job2) + } + } + const job2 = () => { + calls.push('job2') + queueJob(job1) + // The important thing here is that job1 is in the queue twice by this + // point, so we need to invalidate the second job, not the first + invalidateJob(job1) + job1() + } + queueJob(job1) + expect(calls).toEqual([]) + await nextTick() + // job1 should be called twice, not three times + expect(calls).toEqual(['job1', 'job2', 'job1']) + }) }) test('sort job based on id', async () => { diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index b8d1445a183..30d06e105d4 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -111,7 +111,7 @@ function queueFlush() { } export function invalidateJob(job: SchedulerJob) { - const i = queue.indexOf(job) + const i = queue.indexOf(job, flushIndex + 1) if (i > flushIndex) { queue.splice(i, 1) }