diff --git a/packages/runtime-core/__tests__/scheduler.spec.ts b/packages/runtime-core/__tests__/scheduler.spec.ts index 48bc469716c..11205e3c85f 100644 --- a/packages/runtime-core/__tests__/scheduler.spec.ts +++ b/packages/runtime-core/__tests__/scheduler.spec.ts @@ -144,6 +144,7 @@ describe('scheduler', () => { queueJob(job1) // cb2 should execute before the job queueJob(cb2) + queueJob(cb3) } cb1.pre = true @@ -153,9 +154,15 @@ 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('preFlushCb inside queueJob', async () => { diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 923f3ec8251..653f32bdf58 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -62,15 +62,30 @@ export function nextTick( // Use binary-search to find a suitable position in the queue, // so that the queue maintains the increasing order of job's id, // which can prevent the job from being skipped and also can avoid repeated patching. -function findInsertionIndex(id: number) { +function findInsertionIndex(job: SchedulerJob) { // the start index should be `flushIndex + 1` let start = flushIndex + 1 let end = queue.length - + const id = getId(job) + const pre = job.pre + let middle while (start < end) { - const middle = (start + end) >>> 1 + middle = (start + end) >>> 1 const middleJobId = getId(queue[middle]) - middleJobId < id ? (start = middle + 1) : (end = middle) + if (middleJobId === id) { + while ( + queue[middle] && + getId(queue[middle]) === id && + (pre ? queue[middle].pre : true) + ) { + pre ? middle++ : middle-- + } + return middle + } else if (middleJobId < id!) { + start = middle + 1 + } else { + end = middle + } } return start @@ -93,7 +108,7 @@ export function queueJob(job: SchedulerJob) { if (job.id == null) { queue.push(job) } else { - queue.splice(findInsertionIndex(job.id), 0, job) + queue.splice(findInsertionIndex(job), 0, job) } queueFlush() }