diff --git a/packages/runtime-core/__tests__/scheduler.spec.ts b/packages/runtime-core/__tests__/scheduler.spec.ts index 6246a87e8f7..119d0f7080c 100644 --- a/packages/runtime-core/__tests__/scheduler.spec.ts +++ b/packages/runtime-core/__tests__/scheduler.spec.ts @@ -143,6 +143,7 @@ describe('scheduler', () => { queueJob(job1) // cb2 should execute before the job queueJob(cb2) + queueJob(cb3) } cb1.pre = true @@ -152,9 +153,60 @@ describe('scheduler', () => { cb2.pre = true cb2.id = 1 + const cb3 = () => { + calls.push('cb3') + } + cb3.pre = true + cb3.id = 1 + queueJob(cb1) await nextTick() - expect(calls).toEqual(['cb1', 'cb2', 'job1']) + expect(calls).toEqual(['cb1', 'cb2', 'cb3', 'job1']) + }) + + it('should insert jobs after pre jobs with the same id', async () => { + const calls: string[] = [] + const job1 = () => { + calls.push('job1') + } + job1.id = 1 + job1.pre = true + const job2 = () => { + calls.push('job2') + queueJob(job5) + queueJob(job6) + } + job2.id = 2 + job2.pre = true + const job3 = () => { + calls.push('job3') + } + job3.id = 2 + job3.pre = true + const job4 = () => { + calls.push('job4') + } + job4.id = 3 + job4.pre = true + const job5 = () => { + calls.push('job5') + } + job5.id = 2 + const job6 = () => { + calls.push('job6') + } + job6.id = 2 + job6.pre = true + + // We need several jobs to test this properly, otherwise + // findInsertionIndex can yield the correct index by chance + queueJob(job4) + queueJob(job2) + queueJob(job3) + queueJob(job1) + + await nextTick() + expect(calls).toEqual(['job1', 'job2', 'job3', 'job6', 'job5', 'job4']) }) it('preFlushCb inside queueJob', async () => { diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 64c70ab59ca..e4c7fbc0f4d 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -69,8 +69,13 @@ function findInsertionIndex(id: number) { while (start < end) { const middle = (start + end) >>> 1 - const middleJobId = getId(queue[middle]) - middleJobId < id ? (start = middle + 1) : (end = middle) + const middleJob = queue[middle] + const middleJobId = getId(middleJob) + if (middleJobId < id || (middleJobId === id && middleJob.pre)) { + start = middle + 1 + } else { + end = middle + } } return start